The current anatomy of a good movie: Can we do better?
Ever since the “Golden Age” of cinema in the 1930s that marked silent
film a thing of the past, the film industry has witnessed unparalleled
success and growth. From the first technicolor movies like The Wizard of
Oz and Gone With The Wind to the computationally animated The Matrix,
Jurassic Park, and the first fully computer-animated film, Toy Story,
the industry of motion pictures has contributed greatly not only to
technology but also the global economy. Especially in the current
challenging economy and there has been a sharp decline in theater
audience—[shrinking by half in the last 4
years]https://en.wikipedia.org/wiki/IMDb), film distributors are
hesitant to take on a movie unless they can see its success first hand.
Therefore, box-office, or the entire earnings generated through movie
ticket sales, has been recognized as one of the primary indicators to
compare film success. Many rely on it to decide whether to both produce
and watch a film. However, are high grossing movies actually… good? If
so, what else can we use to measure them?
One of the popular other indicators used worldwide to assess a movie is
IMDb rating (or International Movie Database). IMDb rating allows 83
million of its registered users to cast a
vote (from 1 to 10) on every released title in the database. These votes
are then aggregated and summarized as a single IMDb rating visible on
IMDb.com. Accessible to anyone, anywhere, these ratings are a simplified
way to see what people all over the world think about movies and have
been an often-used indicator for a film’s popularity/quality. This led
us to wonder: How do the most profitable movies rank on the IMDb
website?
From our visualization above, the top 20 grossing films have a range of
scores from 6.2 to 8.4 stars. Conversely, the top 20 scored movies on
IMDb globally grossed between 28,419,159 and 1,120,210,896 U.S. Dollars.
When comparing the IMDbscore and amount of money grossed, we can observe
that there isn’t much of a relationship between the rating of a film (or
how “objectively good” a movie is) and the amount of money it makes.
On the other hand, to investigate opinions of films from professionals
and trusted members of the film industry, we can turn to the Academy
Awards.

It seems like a movie’s revenue is not a strong indicator for its
accolades. Among the top 20 movies with the highest worldwide box office
and their Oscars awards, only 11 movies had any nominations at all.
Furthermore, this list gets even more narrowed down as we look into
wins/loses. Titanic, Avatar, Black Panther, and Frozen are the only
movies in the top 20 highest worldwide grossing movies to have had at
least one nomination and won, with Titanic as the most prolific with 11
out of 14 categories (after grouping some of them together).
The Oscars, however, are not an objective means of awardship. In 2015,
the academy “awarded all 20 acting nominations to white actors for the
first of two consecutive years, inspiring April Reign to create the
hashtag #OscarsSoWhite” (Ugwu,
2020).
Leaving the determination of film success to the Academy seems to yield
a celebration of white creators and artists, excluding a whole world of
diverse cinema.

As of 2020, almost half of the U.S. population (42.2%) are people of
color.
Yet, Hollywood fails to consider them when making movies. In the top 20
highest grossing movies of all time, only 2 movies featured a non-white
main character—both of which were Black males. None of these movies
are in the top 5 of this list in terms of profit and grossing while
other underrepresented demographics (Latines, East/South/Southeast
Asians, Native Americans, Afro Latinos, etc.) are left completely off
the screen.
Furthermore, in the history of the Oscars only three women have won the
coveted best director title. This reflects a gendered measure of success
within the film industry, where most of the praise goes to films about
and created by cis men. To measure the representation of women in films,
we can turn to the Bechdel test which was
popularized by Alison Bechdel. The test names three simple criteria: (1)
it has to have at least two women in it, who (2) who talk to each other,
about (3) something besides a man. Although this test seems easy enough,
only 25% of the top scored films and 50% of the top grossing films
passed. Interestingly enough, when comparing the two datasets to an
average Bechdel test score breakdown, we can see that the highest
grossing films all have women and an above average score of “ok” and
“dubious”. However, the highest scored films have less than average “ok”
and dubious” scores.
The trend we have identified here is strong: movies that make the most
money are most often than not white-, male-, and Euro-centric. Even
looking beyond the dollar, we can see how scoring systems and awards are
biased towards this demographic as well. Although the American movie
industry continues achieved commercial success, it historically has, and
continues to, lack sufficient representation. While Hollywood has
undoubtedly created notable films like The Wizard of Oz, Gone With The
Wind, The Matrix, and Jurassic Park, the industry’s focus on white males
has resulted in a significant loss of diverse perspectives and cinematic
experiences. It seems like when we are trying to judge a movie, we
should have a broader repertoire of measurements for how good it is
other than just money.
Code Appendix
library(tidyverse)
library(splitstackshape)
library(dbplyr)
library(stringr)
library(readr)
library(ggplot2)
library(ggthemes)
library(fivethirtyeight)
library(highcharter)
library(scales)
library(rvest)
library(scales)
library(plotly)
library(gapminder)
library(forcats)
library(magrittr)
#Loading raw data
box_office <-read_csv("All Time Worldwide Box Office.csv")
movies_info <- read_csv("movies.csv")
oscars_award <- read_csv("the_oscar_award.csv")
bechdel <- data.frame(bechdel)
bechdelset <- read_csv("bechdelset.csv")
Bechdelmoney <- read_csv("Bechdelmoney.csv")
biopics <- data.frame(biopics)
RatingGross <- read_csv("RatingGross_edit2.csv")
#Data cleaning for figure 1
#average grossing for each top 20 scored
top_score <- movies_info %>%
select(name, score, year, gross) %>%
arrange(desc(score))
#average grossing for each top 20 scored
low_score <- movies_info %>%
select(name, score, year, gross) %>%
arrange(score)
oscarwins <- movies_info %>%
filter(name %in% c("The Lord of the Rings: The Return of the King", "Titanic", "Ben-Hur", "West Side Story", "The English Patient", "The Last Emperor", "Gigi", "Slumdog Millionaire", "Amadeus", "Gandhi")) %>%
summarize(sum=sum(gross))
movies_info %>%
group_by(year) %>%
summarize(total_movies = n(),
american_movies = sum(country == "United States"),
percent_american = 100 * american_movies / total_movies)
doubledata <- movies_info %>%
left_join(RatingGross,
by = c("name", "year" = "Year"))
topgross <- doubledata %>%
filter(doubledata$Rank < 25) %>%
arrange(desc(`WorldwideBox Office`)) %>%
select(name, score.x, Rank, `WorldwideBox Office`)
duplicate_rows <- topgross[duplicated(topgross), ]
topgross <- unique(topgross)
toprate <- doubledata %>%
select(name, score.x, Rank, `WorldwideBox Office`) %>%
arrange(desc(score.x))
topgross_20 <- head(topgross, n = 20) %>%
select(name, score.x, `WorldwideBox Office`)
topscore_20 <- head(toprate, n = 20) %>%
select(name, score.x, `WorldwideBox Office`)
#Data cleaning for figure 2
# Changing Box Office variables into numerical values
box_office <-box_office %>%
mutate(`WorldwideBox Office`=as.numeric(str_replace_all(`WorldwideBox Office`,"[$,]",""))) %>%
mutate(`DomesticBox Office`=as.numeric(str_replace_all(`DomesticBox Office`,"[$,]",""))) %>%
mutate(`InternationalBox Office`=as.numeric(str_replace_all(`InternationalBox Office`,"[$,]","")))
#Getting the Top 20 Box Office
box_office_top20 <- box_office %>%
arrange(Rank) %>%
head(20) %>%
mutate(Movie=ifelse(Movie=="Harry Potter and the Deathly Hallows:…", "Harry Potter and the Deathly Hallows: Part 2",Movie))
#Creating Oscar category data frame
oscars_category <- tibble(
levels(factor(oscars_award$category)))
oscars_category <- oscars_category %>%
rename("category"="levels(factor(oscars_award$category))")
oscars_category <- oscars_category %>%
mutate(broad_category=word(category,1)) %>%
mutate(broad_category=
case_when(broad_category =="ART" ~"ART DIRECTION",
broad_category == "BEST" ~ "BEST PICTURE",
broad_category == "FILM" ~ "FILM EDITING",
broad_category == "ACTOR" | broad_category=="ACTRESS" ~ "ACTING",
TRUE ~ broad_category)
)
#Top 20 Box Office Movies and awards dataset by joining dataframes
box_office_top20_awards <- box_office_top20 %>%
inner_join(oscars_award,by=c("Movie"="film")) %>%
filter(Year == year_film) %>%
inner_join(oscars_category)
box_office_top20_awards <- box_office_top20_awards %>% group_by(Movie,year_film) %>%
summarize(total=n()) %>% inner_join(oscars_award,by=c("Movie"="film")) %>%
filter(year_film.x == year_film.y) %>%
inner_join(oscars_category) %>%
select(Movie, year_film.x,total,year_ceremony,name,winner,broad_category)
#Data cleaning for figure 3
#Changing movie names so they match across movies_info and box_office_top20
movies_info <- movies_info %>% mutate(name=case_when(
name=="Star Wars: Episode VII - The Force Awakens" ~ "Star Wars Ep. VII: The Force Awakens",
name =="Star Wars: Episode VIII - The Last Jedi" ~ "Star Wars Ep. VIII: The Last Jedi",
TRUE~name)) %>%
mutate(company=case_when(
company=="Walt Disney Animation Studios" | company=="Walt Disney Pictures" ~"Walt Disney",
TRUE~company))
#Joinining movies_info and box_office_top20
box_office_top20_info<- box_office_top20 %>%
inner_join(movies_info,by=c("Movie"="name","Year"="year"))
#Making top20 main character's race data frame
top20_race <- data.frame(star=box_office_top20_info$star,Race=c("White","White","White","White","White","White","Black","White","White","White","White","Black","White","White","White","White","White","White","White","White"))
#Joining box_office_top20_info with top20_race dataframe
box_office_top20_info <- box_office_top20_info %>% data.frame(top20_race) %>% select(!star.1)
#Data cleaning for figure 4
bechdelset <- bechdelset %>%
mutate(set_factor = factor(set))
bechdelsetav <- bechdelset %>%
group_by(set_factor, clean_test) %>%
summarize(count = n ())
bechdelsetav <- bechdelsetav %>%
mutate(percent = count/ 20 * 100)
bechdelav <- bechdel %>%
group_by(clean_test) %>%
summarize (count = n ())
bechdelav <- bechdelav %>%
mutate(percent = round(count/ 1794 * 100)) %>%
mutate(set_factor = "Average Bechdel Scores")
jointav <- rbind(bechdelsetav, bechdelav)
jointav$clean_test <- factor(jointav$clean_test, levels = c("nowomen", "notalk", "men", "dubious", "ok"))
#Figure 1
colors <- c("#AC2528", "#E4792C", "#764484", "#346491", "#448746")
fig1<-plot_ly(bechdelset, x = ~score.x, y = ~`WorldwideBox Office`, color = ~clean_test, colors = colors, type = 'scatter', mode = 'markers',
hoverinfo = 'text',
text = ~paste('</br>', name,
'</br>', "IMDB Score:", score.x,
'</br>', "Worldwide Grossing:", comma(`WorldwideBox Office`))) %>%
layout(title = 'IMDB Score vs. Amount of Money Grossed',
xaxis = list(title = 'IMDB Score'),
yaxis = list(title = 'Worldwide Box Office'),
legend = list(title = list(text = "Bechdel Test Score"),
titles = list(topgross_20 = "Top 20 Grossing", topscore_20 = "Top 20 Scored")))
#Figure 2
fig2<-box_office_top20_awards %>%
ggplot(aes(x = fct_reorder(Movie, total,.fun=sum),alpha=winner,fill=fct_reorder(broad_category,winner))) +
geom_bar()+
theme_classic() +
theme(legend.position = "right")+
scale_fill_viridis_d()+
coord_flip()+
labs(y="Total Nominations",x="Movie",title="Top 20 Movies with Highest Worldwide Box Office vs Oscars Awards",subtitle = "By Category and Wins",fill="Category",alpha="Winner")+
theme(plot.title = element_text(face="bold",size=16),plot.subtitle = element_text(size=14),axis.title.x = element_text(size=14),axis.text.x = element_text(size=12),axis.title.y = element_text(size=14),axis.text.y = element_text(size=12))
#Figure 3
fig3<-box_office_top20_info %>%
mutate(Profit=gross-budget) %>%
ggplot(aes(x=budget,y=gross,color=Race,size=Profit)) +
geom_point()+
theme_minimal()+
scale_x_continuous(labels = label_comma())+
scale_y_continuous(labels = label_comma())+
scale_size_continuous(labels = label_comma())+
scale_color_viridis_d(option="E")+
labs(y="Total Gross",x="Budget",title="Top 20 Movies with Highest Worldwide Box Office",subtitle = "By Profit and Race of Main Character")+
theme(plot.title = element_text(face="bold",size=12),plot.subtitle = element_text(size=10),axis.text.x = element_text(size=8))+
annotate("text",x=200000000,y=1430000000,label="Black Panther",size=3,color="red3")+
annotate("text",x=260000000,y=1750000000,label="The Lion King (2019)",size=3,color="red3")
#Figure 4
fig4<-hchart(jointav, "column", hcaes(x = set_factor, y = count, group = clean_test), stacking = "percent") %>%
hc_title(text = "Bechdel Test Scores") %>%
hc_colors(colors) %>%
hc_tooltip(pointFormat = "{series.name}: {point.percentage:.1f}%") %>%
hc_yAxis(title = "Percentage", labels = list(format = '{value}%')) %>%
hc_xAxis(title = NULL) %>%
hc_colors(colors) %>%
hc_legend(enabled = TRUE)
LS0tCnRpdGxlOiAiTWVhc3VyaW5nIGEgTW92aWXigJlzIFN1Y2Nlc3MgQmV5b25kIHRoZSBEb2xsYXI6IDxicj4gQXJlIFRoZSBIaWdoZXN0IEdyb3NzaW5nIE1vdmllcyBvZiBBbGwgVGltZXMgQWN0dWFsbHnigKZHb29kPyIKYXV0aG9yOiAiRW1tYSBNYWxjb2xtLCBOYSBOZ3V5ZW4iCmRhdGU6ICIyMDIzLTA0LTExIgpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgc3BsaXRfYnk6IE5PTkUKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDoKICAgICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogNzIKLS0tCgo8IS0tLSBCZWdpbiBzdHlsaW5nIGNvZGUuIC0tLT4KCmBgYHs9aHRtbH0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KLyogV2hvbGUgZG9jdW1lbnQ6ICovCmJvZHl7CiAgZm9udC1mYW1pbHk6ICJQYWxhdGlubyBMaW5vdHlwZSIsICJCb29rIEFudGlxdWEiLCBQYWxhdGlubywgc2VyaWY7CiAgZm9udC1zaXplOiAxMnB0Owp9CmgxLnRpdGxlIHsKICBmb250LXNpemU6IDM4cHg7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9Cmg0LmF1dGhvciB7CiAgZm9udC1zaXplOiAxOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5kYXRlIHsKICBmb250LXNpemU6IDE4cHg7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9Cjwvc3R5bGU+CmBgYAo8IS0tLSBFbmQgc3R5bGluZyBjb2RlLiAtLS0+CgpgYGB7cixlY2hvPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgdGlkeSA9IFRSVUUpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNwbGl0c3RhY2tzaGFwZSkKbGlicmFyeShkYnBseXIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShyZWFkcikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdndGhlbWVzKQpsaWJyYXJ5KGZpdmV0aGlydHllaWdodCkKbGlicmFyeShoaWdoY2hhcnRlcikKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocnZlc3QpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnYXBtaW5kZXIpCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShtYWdyaXR0cikKCgojTG9hZGluZyByYXcgZGF0YQpib3hfb2ZmaWNlIDwtcmVhZF9jc3YoIi4uL2RhdGEvQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2UuY3N2IikKbW92aWVzX2luZm8gPC0gcmVhZF9jc3YoIi4uL2RhdGEvbW92aWVzLmNzdiIpCm9zY2Fyc19hd2FyZCA8LSByZWFkX2NzdigiLi4vZGF0YS90aGVfb3NjYXJfYXdhcmQuY3N2IikKYmVjaGRlbCA8LSBkYXRhLmZyYW1lKGJlY2hkZWwpCmJlY2hkZWxzZXQgPC0gcmVhZF9jc3YoIi4uL2RhdGEvYmVjaGRlbHNldC5jc3YiKQpCZWNoZGVsbW9uZXkgPC0gcmVhZF9jc3YoIi4uL2RhdGEvQmVjaGRlbG1vbmV5LmNzdiIpCmJpb3BpY3MgPC0gZGF0YS5mcmFtZShiaW9waWNzKQpSYXRpbmdHcm9zcyA8LSByZWFkX2NzdigiLi4vZGF0YS9SYXRpbmdHcm9zc19lZGl0Mi5jc3YiKQoKYGBgCgpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDEKI2F2ZXJhZ2UgZ3Jvc3NpbmcgZm9yIGVhY2ggdG9wIDIwIHNjb3JlZAoKdG9wX3Njb3JlIDwtIG1vdmllc19pbmZvICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUsIHllYXIsIGdyb3NzKSAlPiUgCiAgYXJyYW5nZShkZXNjKHNjb3JlKSkKCiNhdmVyYWdlIGdyb3NzaW5nIGZvciBlYWNoIHRvcCAyMCBzY29yZWQKCmxvd19zY29yZSA8LSBtb3ZpZXNfaW5mbyAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLCB5ZWFyLCBncm9zcykgJT4lIAogIGFycmFuZ2Uoc2NvcmUpCgoKb3NjYXJ3aW5zIDwtICBtb3ZpZXNfaW5mbyAlPiUgCiAgZmlsdGVyKG5hbWUgJWluJSBjKCJUaGUgTG9yZCBvZiB0aGUgUmluZ3M6IFRoZSBSZXR1cm4gb2YgdGhlIEtpbmciLCAiVGl0YW5pYyIsICJCZW4tSHVyIiwgIldlc3QgU2lkZSBTdG9yeSIsICJUaGUgRW5nbGlzaCBQYXRpZW50IiwgIlRoZSBMYXN0IEVtcGVyb3IiLCAiR2lnaSIsICJTbHVtZG9nIE1pbGxpb25haXJlIiwgIkFtYWRldXMiLCAiR2FuZGhpIikpICU+JSAKIHN1bW1hcml6ZShzdW09c3VtKGdyb3NzKSkKCgpkb3VibGVkYXRhIDwtIG1vdmllc19pbmZvICU+JQogIGxlZnRfam9pbihSYXRpbmdHcm9zcywKICAgIGJ5ID0gYygibmFtZSIsICJ5ZWFyIiA9ICJZZWFyIikpCgoKdG9wZ3Jvc3MgPC0gZG91YmxlZGF0YSAlPiUgCiAgZmlsdGVyKGRvdWJsZWRhdGEkUmFuayA8IDI1KSAlPiUgIAogIGFycmFuZ2UoZGVzYyhgV29ybGR3aWRlQm94IE9mZmljZWApKSAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLngsIFJhbmssIGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkKCmR1cGxpY2F0ZV9yb3dzIDwtIHRvcGdyb3NzW2R1cGxpY2F0ZWQodG9wZ3Jvc3MpLCBdCnRvcGdyb3NzIDwtIHVuaXF1ZSh0b3Bncm9zcykKCgp0b3ByYXRlIDwtIGRvdWJsZWRhdGEgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBSYW5rLCBgV29ybGR3aWRlQm94IE9mZmljZWApICU+JSAKICBhcnJhbmdlKGRlc2Moc2NvcmUueCkpIAoKICAgICAKdG9wZ3Jvc3NfMjAgPC0gaGVhZCh0b3Bncm9zcywgbiA9IDIwKSAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLngsIGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkKdG9wc2NvcmVfMjAgPC0gaGVhZCh0b3ByYXRlLCBuID0gMjApICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgYFdvcmxkd2lkZUJveCBPZmZpY2VgKQoKCgpgYGAKCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgMgojIENoYW5naW5nIEJveCBPZmZpY2UgdmFyaWFibGVzIGludG8gbnVtZXJpY2FsIHZhbHVlcwpib3hfb2ZmaWNlIDwtYm94X29mZmljZSAlPiUgCiBtdXRhdGUoYFdvcmxkd2lkZUJveCBPZmZpY2VgPWFzLm51bWVyaWMoc3RyX3JlcGxhY2VfYWxsKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCwiWyQsXSIsIiIpKSkgJT4lIAogIG11dGF0ZShgRG9tZXN0aWNCb3ggT2ZmaWNlYD1hcy5udW1lcmljKHN0cl9yZXBsYWNlX2FsbChgRG9tZXN0aWNCb3ggT2ZmaWNlYCwiWyQsXSIsIiIpKSkgJT4lCiAgbXV0YXRlKGBJbnRlcm5hdGlvbmFsQm94IE9mZmljZWA9YXMubnVtZXJpYyhzdHJfcmVwbGFjZV9hbGwoYEludGVybmF0aW9uYWxCb3ggT2ZmaWNlYCwiWyQsXSIsIiIpKSkKCiNHZXR0aW5nIHRoZSBUb3AgMjAgQm94IE9mZmljZQpib3hfb2ZmaWNlX3RvcDIwIDwtIGJveF9vZmZpY2UgJT4lICAKICBhcnJhbmdlKFJhbmspICU+JSAKICBoZWFkKDIwKSAlPiUgCiAgbXV0YXRlKE1vdmllPWlmZWxzZShNb3ZpZT09IkhhcnJ5IFBvdHRlciBhbmQgdGhlIERlYXRobHkgSGFsbG93czrigKYiLCAiSGFycnkgUG90dGVyIGFuZCB0aGUgRGVhdGhseSBIYWxsb3dzOiBQYXJ0IDIiLE1vdmllKSkKCgojQ3JlYXRpbmcgT3NjYXIgY2F0ZWdvcnkgZGF0YSBmcmFtZQpvc2NhcnNfY2F0ZWdvcnkgPC0gdGliYmxlKApsZXZlbHMoZmFjdG9yKG9zY2Fyc19hd2FyZCRjYXRlZ29yeSkpKQogIAoKb3NjYXJzX2NhdGVnb3J5IDwtIG9zY2Fyc19jYXRlZ29yeSAlPiUgCiAgcmVuYW1lKCJjYXRlZ29yeSI9ImxldmVscyhmYWN0b3Iob3NjYXJzX2F3YXJkJGNhdGVnb3J5KSkiKSAKICAKCm9zY2Fyc19jYXRlZ29yeSA8LSBvc2NhcnNfY2F0ZWdvcnkgJT4lIAogIG11dGF0ZShicm9hZF9jYXRlZ29yeT13b3JkKGNhdGVnb3J5LDEpKSAlPiUgCiAgbXV0YXRlKGJyb2FkX2NhdGVnb3J5PQogICAgICAgICAgIGNhc2Vfd2hlbihicm9hZF9jYXRlZ29yeSA9PSJBUlQiIH4iQVJUIERJUkVDVElPTiIsCiAgICAgICAgICAgICAgICAgICAgIGJyb2FkX2NhdGVnb3J5ID09ICJCRVNUIiB+ICJCRVNUIFBJQ1RVUkUiLAogICAgICAgICAgICAgICAgICAgICBicm9hZF9jYXRlZ29yeSA9PSAiRklMTSIgfiAiRklMTSBFRElUSU5HIiwKICAgICAgICAgICAgICAgICAgICAgYnJvYWRfY2F0ZWdvcnkgPT0gIkFDVE9SIiB8IGJyb2FkX2NhdGVnb3J5PT0iQUNUUkVTUyIgfiAiQUNUSU5HIiwKICAgICAgICAgICAgICAgICAgICBUUlVFIH4gYnJvYWRfY2F0ZWdvcnkpCiAgICAgICAgICAgICkgCgojVG9wIDIwIEJveCBPZmZpY2UgTW92aWVzIGFuZCBhd2FyZHMgZGF0YXNldCBieSBqb2luaW5nIGRhdGFmcmFtZXMKYm94X29mZmljZV90b3AyMF9hd2FyZHMgPC0gYm94X29mZmljZV90b3AyMCAlPiUgCiAgaW5uZXJfam9pbihvc2NhcnNfYXdhcmQsYnk9YygiTW92aWUiPSJmaWxtIikpICU+JSAKICBmaWx0ZXIoWWVhciA9PSB5ZWFyX2ZpbG0pICU+JSAKICBpbm5lcl9qb2luKG9zY2Fyc19jYXRlZ29yeSkgIAoKYm94X29mZmljZV90b3AyMF9hd2FyZHMgPC0gYm94X29mZmljZV90b3AyMF9hd2FyZHMgJT4lIGdyb3VwX2J5KE1vdmllLHllYXJfZmlsbSkgJT4lIAogIHN1bW1hcml6ZSh0b3RhbD1uKCkpICU+JSAgaW5uZXJfam9pbihvc2NhcnNfYXdhcmQsYnk9YygiTW92aWUiPSJmaWxtIikpICU+JSAKICBmaWx0ZXIoeWVhcl9maWxtLnggPT0geWVhcl9maWxtLnkpICU+JSAKICBpbm5lcl9qb2luKG9zY2Fyc19jYXRlZ29yeSkgICU+JSAKICBzZWxlY3QoTW92aWUsIHllYXJfZmlsbS54LHRvdGFsLHllYXJfY2VyZW1vbnksbmFtZSx3aW5uZXIsYnJvYWRfY2F0ZWdvcnkpCmBgYAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0RhdGEgY2xlYW5pbmcgZm9yIGZpZ3VyZSAzCiNDaGFuZ2luZyBtb3ZpZSBuYW1lcyBzbyB0aGV5IG1hdGNoIGFjcm9zcyBtb3ZpZXNfaW5mbyBhbmQgYm94X29mZmljZV90b3AyMAoKbW92aWVzX2luZm8gPC0gbW92aWVzX2luZm8gJT4lICBtdXRhdGUobmFtZT1jYXNlX3doZW4oCiAgbmFtZT09IlN0YXIgV2FyczogRXBpc29kZSBWSUkgLSBUaGUgRm9yY2UgQXdha2VucyIgfiAiU3RhciBXYXJzIEVwLiBWSUk6IFRoZSBGb3JjZSBBd2FrZW5zIiwKICBuYW1lID09IlN0YXIgV2FyczogRXBpc29kZSBWSUlJIC0gVGhlIExhc3QgSmVkaSIgfiAiU3RhciBXYXJzIEVwLiBWSUlJOiBUaGUgTGFzdCBKZWRpIiwKVFJVRX5uYW1lKSkgJT4lIAogIG11dGF0ZShjb21wYW55PWNhc2Vfd2hlbigKICAgIGNvbXBhbnk9PSJXYWx0IERpc25leSBBbmltYXRpb24gU3R1ZGlvcyIgfCBjb21wYW55PT0iV2FsdCBEaXNuZXkgUGljdHVyZXMiIH4iV2FsdCBEaXNuZXkiLApUUlVFfmNvbXBhbnkpKQoKI0pvaW5pbmluZyBtb3ZpZXNfaW5mbyBhbmQgYm94X29mZmljZV90b3AyMAoKYm94X29mZmljZV90b3AyMF9pbmZvPC0gYm94X29mZmljZV90b3AyMCAlPiUKICBpbm5lcl9qb2luKG1vdmllc19pbmZvLGJ5PWMoIk1vdmllIj0ibmFtZSIsIlllYXIiPSJ5ZWFyIikpCgojTWFraW5nIHRvcDIwIG1haW4gY2hhcmFjdGVyJ3MgcmFjZSBkYXRhIGZyYW1lCnRvcDIwX3JhY2UgPC0gZGF0YS5mcmFtZShzdGFyPWJveF9vZmZpY2VfdG9wMjBfaW5mbyRzdGFyLFJhY2U9YygiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiQmxhY2siLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIkJsYWNrIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIpKQoKI0pvaW5pbmcgYm94X29mZmljZV90b3AyMF9pbmZvIHdpdGggdG9wMjBfcmFjZSBkYXRhZnJhbWUKYm94X29mZmljZV90b3AyMF9pbmZvIDwtIGJveF9vZmZpY2VfdG9wMjBfaW5mbyAlPiUgZGF0YS5mcmFtZSh0b3AyMF9yYWNlKSAlPiUgc2VsZWN0KCFzdGFyLjEpCgpgYGAKCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgNAoKYmVjaGRlbHNldCA8LSBiZWNoZGVsc2V0ICU+JSAKICBtdXRhdGUoc2V0X2ZhY3RvciA9IGZhY3RvcihzZXQpKSAKCmJlY2hkZWxzZXRhdiA8LSBiZWNoZGVsc2V0ICU+JSAKICBncm91cF9ieShzZXRfZmFjdG9yLCBjbGVhbl90ZXN0KSAlPiUgCiAgc3VtbWFyaXplKGNvdW50ID0gbiAoKSkKCmJlY2hkZWxzZXRhdiA8LSBiZWNoZGVsc2V0YXYgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvIDIwICogMTAwKQoKYmVjaGRlbGF2IDwtIGJlY2hkZWwgJT4lIAogIGdyb3VwX2J5KGNsZWFuX3Rlc3QpICU+JSAgCiAgc3VtbWFyaXplIChjb3VudCA9IG4gKCkpCgpiZWNoZGVsYXYgPC0gYmVjaGRlbGF2ICU+JSAgCiAgICBtdXRhdGUocGVyY2VudCA9IHJvdW5kKGNvdW50LyAxNzk0ICogMTAwKSkgJT4lIAogICAgbXV0YXRlKHNldF9mYWN0b3IgPSAiQXZlcmFnZSBCZWNoZGVsIFNjb3JlcyIpCgpqb2ludGF2IDwtIHJiaW5kKGJlY2hkZWxzZXRhdiwgYmVjaGRlbGF2KSAKCgpqb2ludGF2JGNsZWFuX3Rlc3QgPC0gZmFjdG9yKGpvaW50YXYkY2xlYW5fdGVzdCwgbGV2ZWxzID0gYygibm93b21lbiIsICJub3RhbGsiLCAibWVuIiwgImR1YmlvdXMiLCAib2siKSkKCmBgYAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSxmaWcuYWx0PSJBIHNjYXR0ZXIgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgSU1EYiBzY29yZSBhbmQgd29ybGR3aWRlIGJveCBvZmZpY2UgZ3Jvc3MgZm9yIG1vdmllcyB3aXRoIGRpZmZlcmVudCBCZWNoZGVsIHRlc3Qgc2NvcmVzLiBFYWNoIHBvaW50IHJlcHJlc2VudHMgYSBtb3ZpZSBhbmQgaXMgY29sb3JlZCBiYXNlZCBvbiBpdHMgQmVjaGRlbCB0ZXN0IHNjb3JlLiBUaGUgbGVnZW5kIHNob3dzIHRoZSBmaXZlIEJlY2hkZWwgdGVzdCBzY29yZXM6IG5vIHdvbWVuLCBubyB0YWxrLCBtZW4sIGR1YmlvdXMsIGFuZCBvay4gVGhlIHgtYXhpcyByZXByZXNlbnRzIHRoZSBJTURiIHNjb3JlLCBhbmQgdGhlIHktYXhpcyByZXByZXNlbnRzIHRoZSB3b3JsZHdpZGUgYm94IG9mZmljZSBncm9zcyBpbiBtaWxsaW9ucy8gYmlsbGlvbnMgb2YgZG9sbGFycy4gVGhlIHRvb2x0aXAgZGlzcGxheXMgdGhlIG1vdmllIG5hbWUsIElNRGIgc2NvcmUsIGFuZCB3b3JsZHdpZGUgZ3Jvc3NpbmcgZm9yIGVhY2ggcG9pbnQuIn0KI0ZpZ3VyZSAxCmNvbG9ycyA8LSBjKCIjQUMyNTI4IiwgIiNFNDc5MkMiLCAiIzc2NDQ4NCIsICIjMzQ2NDkxIiwgIiM0NDg3NDYiKQoKZmlnMTwtcGxvdF9seShiZWNoZGVsc2V0LCB4ID0gfnNjb3JlLngsIHkgPSB+YFdvcmxkd2lkZUJveCBPZmZpY2VgLCBjb2xvciA9IH5jbGVhbl90ZXN0LCBjb2xvcnMgPSBjb2xvcnMsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbWFya2VycycsCiAgaG92ZXJpbmZvID0gJ3RleHQnLAogIHRleHQgPSB+cGFzdGUoJzwvYnI+JywgbmFtZSwgCiAgICAgICAgICAgICAgICAnPC9icj4nLCAiSU1EQiBTY29yZToiLCBzY29yZS54LCAKICAgICAgICAgICAgICAgICc8L2JyPicsICJXb3JsZHdpZGUgR3Jvc3Npbmc6IiwgY29tbWEoYFdvcmxkd2lkZUJveCBPZmZpY2VgKSkpICU+JSAKICBsYXlvdXQodGl0bGUgPSAnSU1EQiBTY29yZSB2cy4gQW1vdW50IG9mIE1vbmV5IEdyb3NzZWQnLCAKICAgICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0lNREIgU2NvcmUnKSwgCiAgICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICdXb3JsZHdpZGUgQm94IE9mZmljZScpLCAKICAgICAgICAgICBsZWdlbmQgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0ID0gIkJlY2hkZWwgVGVzdCBTY29yZSIpLAogICAgICAgICAgICAgICAgICAgICAgIHRpdGxlcyA9IGxpc3QodG9wZ3Jvc3NfMjAgPSAiVG9wIDIwIEdyb3NzaW5nIiwgdG9wc2NvcmVfMjAgPSAiVG9wIDIwIFNjb3JlZCIpKSkKCgoKCmBgYAoKYGBge3IsZmlnLmFsdD0iVGhpcyBiYXIgZ3JhcGggc2hvd3MgdGhlIHRvdGFsIG51bWJlciBvZiBvc2NhciBhd2FyZHMgbm9taW5hdGlvbnMgb2YgdGhlIHRvcCAyMCBtb3ZpZXMgd2l0aCB0aGUgaGlnaGVzdCBXb3JsZHdpZGUgQm94IE9mZmljZSBieSBDYXRlZ29yeSBhbmQgV2lucyIsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQojRmlndXJlIDIKCmZpZzI8LWJveF9vZmZpY2VfdG9wMjBfYXdhcmRzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmVvcmRlcihNb3ZpZSwgdG90YWwsLmZ1bj1zdW0pLGFscGhhPXdpbm5lcixmaWxsPWZjdF9yZW9yZGVyKGJyb2FkX2NhdGVnb3J5LHdpbm5lcikpKSArIAogIGdlb21fYmFyKCkrCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSsKICBzY2FsZV9maWxsX3ZpcmlkaXNfZCgpKwogIGNvb3JkX2ZsaXAoKSsKICBsYWJzKHk9IlRvdGFsIE5vbWluYXRpb25zIix4PSJNb3ZpZSIsdGl0bGU9IlRvcCAyMCBNb3ZpZXMgd2l0aCBIaWdoZXN0IFdvcmxkd2lkZSBCb3ggT2ZmaWNlIHZzIE9zY2FycyBBd2FyZHMiLHN1YnRpdGxlID0gIkJ5IENhdGVnb3J5IGFuZCBXaW5zIixmaWxsPSJDYXRlZ29yeSIsYWxwaGE9Ildpbm5lciIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsc2l6ZT0xNikscGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSxheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT0xMiksYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKQoKCmBgYAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSxmaWcuYWx0PSJUaGlzIHNjYXR0ZXIgcGxvdCBkaXNwbGF5cyB0aGUgdG9wIDIwIGhpZ2hlc3QgZ3Jvc3NpbmcgbW92aWVzIG9mIGFsbCB0aW1lIGJ5IHRoZWlyIHByb2ZpdCBhbmQgdGhlIG1haW4gY2hhcmFjdGVyJ3MgcmFjZS4gSXQgc2hvd3MgdGhhdCBvdXQgb2YgMjAgbW92aWVzLCAyIGhhcyBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3Rlci4ifQojRmlndXJlIDMKZmlnMzwtYm94X29mZmljZV90b3AyMF9pbmZvICU+JSAKICBtdXRhdGUoUHJvZml0PWdyb3NzLWJ1ZGdldCkgJT4lCiAgZ2dwbG90KGFlcyh4PWJ1ZGdldCx5PWdyb3NzLGNvbG9yPVJhY2Usc2l6ZT1Qcm9maXQpKSArCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX21pbmltYWwoKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfY29tbWEoKSkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX2NvbW1hKCkpKwogIHNjYWxlX3NpemVfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9jb21tYSgpKSsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uPSJFIikrCiAgbGFicyh5PSJUb3RhbCBHcm9zcyIseD0iQnVkZ2V0Iix0aXRsZT0iVG9wIDIwIE1vdmllcyB3aXRoIEhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UiLHN1YnRpdGxlID0gIkJ5IFByb2ZpdCBhbmQgUmFjZSBvZiBNYWluIENoYXJhY3RlciIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsc2l6ZT0xMikscGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTgpKSsKICBhbm5vdGF0ZSgidGV4dCIseD0yMDAwMDAwMDAseT0xNDMwMDAwMDAwLGxhYmVsPSJCbGFjayBQYW50aGVyIixzaXplPTMsY29sb3I9InJlZDMiKSsKICAgYW5ub3RhdGUoInRleHQiLHg9MjYwMDAwMDAwLHk9MTc1MDAwMDAwMCxsYWJlbD0iVGhlIExpb24gS2luZyAoMjAxOSkiLHNpemU9Myxjb2xvcj0icmVkMyIpCgogIApgYGAKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGZpZy5hbHQ9IkEgc3RhY2tlZCBjb2x1bW4gY2hhcnQgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBkaXN0cmlidXRpb24gb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0IGJ5IGRpZmZlcmVudCBtb3ZpZSBzZXRzLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIG1vdmllIHNldHMsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0LiBUaGUgY2hhcnQgaXMgZGl2aWRlZCBpbnRvIGZpdmUgY2F0ZWdvcmllcyBiYXNlZCBvbiB0aGUgQmVjaGRlbCB0ZXN0IHNjb3JlOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB0b29sdGlwIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIG1vdmllcyBmb3IgZWFjaCBjYXRlZ29yeSBhbmQgbW92aWUgc2V0LiJ9CiNGaWd1cmUgNAoKCmZpZzQ8LWhjaGFydChqb2ludGF2LCAiY29sdW1uIiwgaGNhZXMoeCA9IHNldF9mYWN0b3IsIHkgPSBjb3VudCwgZ3JvdXAgPSBjbGVhbl90ZXN0KSwgc3RhY2tpbmcgPSAicGVyY2VudCIpICU+JSAKICBoY190aXRsZSh0ZXh0ID0gIkJlY2hkZWwgVGVzdCBTY29yZXMiKSAlPiUgCiAgaGNfY29sb3JzKGNvbG9ycykgJT4lIAogIGhjX3Rvb2x0aXAocG9pbnRGb3JtYXQgPSAie3Nlcmllcy5uYW1lfToge3BvaW50LnBlcmNlbnRhZ2U6LjFmfSUiKSAlPiUgCiAgaGNfeUF4aXModGl0bGUgPSAiUGVyY2VudGFnZSIsIGxhYmVscyA9IGxpc3QoZm9ybWF0ID0gJ3t2YWx1ZX0lJykpICU+JQogIGhjX3hBeGlzKHRpdGxlID0gTlVMTCkgJT4lIAogIGhjX2NvbG9ycyhjb2xvcnMpICU+JSAKICBoY19sZWdlbmQoZW5hYmxlZCA9IFRSVUUpCmBgYAoKIyBUaGUgY3VycmVudCBhbmF0b215IG9mIGEgZ29vZCBtb3ZpZTogQ2FuIHdlIGRvIGJldHRlcj8KCkV2ZXIgc2luY2UgdGhlICJHb2xkZW4gQWdlIiBvZiBjaW5lbWEgaW4gdGhlIDE5MzBzIHRoYXQgbWFya2VkIHNpbGVudApmaWxtIGEgdGhpbmcgb2YgdGhlIHBhc3QsIHRoZSBmaWxtIGluZHVzdHJ5IGhhcyB3aXRuZXNzZWQgdW5wYXJhbGxlbGVkCnN1Y2Nlc3MgYW5kIGdyb3d0aC4gRnJvbSB0aGUgZmlyc3QgdGVjaG5pY29sb3IgbW92aWVzIGxpa2UgVGhlIFdpemFyZCBvZgpPeiBhbmQgR29uZSBXaXRoIFRoZSBXaW5kIHRvIHRoZSBjb21wdXRhdGlvbmFsbHkgYW5pbWF0ZWQgVGhlIE1hdHJpeCwKSnVyYXNzaWMgUGFyaywgYW5kIHRoZSBmaXJzdCBmdWxseSBjb21wdXRlci1hbmltYXRlZCBmaWxtLCBUb3kgU3RvcnksCnRoZSBpbmR1c3RyeSBvZiBtb3Rpb24gcGljdHVyZXMgaGFzIGNvbnRyaWJ1dGVkIGdyZWF0bHkgbm90IG9ubHkgdG8KdGVjaG5vbG9neSBidXQgYWxzbyB0aGUgZ2xvYmFsIGVjb25vbXkuIEVzcGVjaWFsbHkgaW4gdGhlIGN1cnJlbnQKY2hhbGxlbmdpbmcgZWNvbm9teSBhbmQgdGhlcmUgaGFzIGJlZW4gYSBzaGFycCBkZWNsaW5lIGluIHRoZWF0ZXIKYXVkaWVuY2UtLS1bc2hyaW5raW5nIGJ5IGhhbGYgaW4gdGhlIGxhc3QgNAp5ZWFyc108aHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSU1EYj4pLCBmaWxtIGRpc3RyaWJ1dG9ycyBhcmUKaGVzaXRhbnQgdG8gdGFrZSBvbiBhIG1vdmllIHVubGVzcyB0aGV5IGNhbiBzZWUgaXRzIHN1Y2Nlc3MgZmlyc3QgaGFuZC4KVGhlcmVmb3JlLCBib3gtb2ZmaWNlLCBvciB0aGUgZW50aXJlIGVhcm5pbmdzIGdlbmVyYXRlZCB0aHJvdWdoIG1vdmllCnRpY2tldCBzYWxlcywgaGFzIGJlZW4gcmVjb2duaXplZCBhcyBvbmUgb2YgdGhlIHByaW1hcnkgaW5kaWNhdG9ycyB0bwpjb21wYXJlIGZpbG0gc3VjY2Vzcy4gTWFueSByZWx5IG9uIGl0IHRvIGRlY2lkZSB3aGV0aGVyIHRvIGJvdGggcHJvZHVjZQphbmQgd2F0Y2ggYSBmaWxtLiBIb3dldmVyLCBhcmUgaGlnaCBncm9zc2luZyBtb3ZpZXMgYWN0dWFsbHkuLi4gZ29vZD8gSWYKc28sIHdoYXQgZWxzZSBjYW4gd2UgdXNlIHRvIG1lYXN1cmUgdGhlbT8KCk9uZSBvZiB0aGUgcG9wdWxhciBvdGhlciBpbmRpY2F0b3JzIHVzZWQgd29ybGR3aWRlIHRvIGFzc2VzcyBhIG1vdmllIGlzCklNRGIgcmF0aW5nIChvciBJbnRlcm5hdGlvbmFsIE1vdmllIERhdGFiYXNlKS4gSU1EYiByYXRpbmcgYWxsb3dzIFs4MwptaWxsaW9uXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcpIG9mIGl0cyByZWdpc3RlcmVkIHVzZXJzIHRvIGNhc3QgYQp2b3RlIChmcm9tIDEgdG8gMTApIG9uIGV2ZXJ5IHJlbGVhc2VkIHRpdGxlIGluIHRoZSBkYXRhYmFzZS4gVGhlc2Ugdm90ZXMKYXJlIHRoZW4gYWdncmVnYXRlZCBhbmQgc3VtbWFyaXplZCBhcyBhIHNpbmdsZSBJTURiIHJhdGluZyB2aXNpYmxlIG9uCklNRGIuY29tLiBBY2Nlc3NpYmxlIHRvIGFueW9uZSwgYW55d2hlcmUsIHRoZXNlIHJhdGluZ3MgYXJlIGEgc2ltcGxpZmllZAp3YXkgdG8gc2VlIHdoYXQgcGVvcGxlIGFsbCBvdmVyIHRoZSB3b3JsZCB0aGluayBhYm91dCBtb3ZpZXMgYW5kIGhhdmUKYmVlbiBhbiBvZnRlbi11c2VkIGluZGljYXRvciBmb3IgYSBmaWxtJ3MgcG9wdWxhcml0eS9xdWFsaXR5LiBUaGlzIGxlZAp1cyB0byB3b25kZXI6ICpIb3cgZG8gdGhlIG1vc3QgcHJvZml0YWJsZSBtb3ZpZXMgcmFuayBvbiB0aGUgSU1EYgp3ZWJzaXRlPyoKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGZpZy5hbHQ9IkEgc2NhdHRlciBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBJTURiIHNjb3JlIGFuZCB3b3JsZHdpZGUgYm94IG9mZmljZSBncm9zcyBmb3IgbW92aWVzIHdpdGggZGlmZmVyZW50IEJlY2hkZWwgdGVzdCBzY29yZXMuIEVhY2ggcG9pbnQgcmVwcmVzZW50cyBhIG1vdmllIGFuZCBpcyBjb2xvcmVkIGJhc2VkIG9uIGl0cyBCZWNoZGVsIHRlc3Qgc2NvcmUuIFRoZSBsZWdlbmQgc2hvd3MgdGhlIGZpdmUgQmVjaGRlbCB0ZXN0IHNjb3Jlczogbm8gd29tZW4sIG5vIHRhbGssIG1lbiwgZHViaW91cywgYW5kIG9rLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIElNRGIgc2NvcmUsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHdvcmxkd2lkZSBib3ggb2ZmaWNlIGdyb3NzIGluIG1pbGxpb25zLyBiaWxsaW9ucyBvZiBkb2xsYXJzLiBUaGUgdG9vbHRpcCBkaXNwbGF5cyB0aGUgbW92aWUgbmFtZSwgSU1EYiBzY29yZSwgYW5kIHdvcmxkd2lkZSBncm9zc2luZyBmb3IgZWFjaCBwb2ludC4ifQpmaWcxCmBgYAoKRnJvbSBvdXIgdmlzdWFsaXphdGlvbiBhYm92ZSwgdGhlIHRvcCAyMCBncm9zc2luZyBmaWxtcyBoYXZlIGEgcmFuZ2Ugb2YKc2NvcmVzIGZyb20gNi4yIHRvIDguNCBzdGFycy4gQ29udmVyc2VseSwgdGhlIHRvcCAyMCBzY29yZWQgbW92aWVzIG9uCklNRGIgZ2xvYmFsbHkgZ3Jvc3NlZCBiZXR3ZWVuIDI4LDQxOSwxNTkgYW5kIDEsMTIwLDIxMCw4OTYgVS5TLiBEb2xsYXJzLgpXaGVuIGNvbXBhcmluZyB0aGUgSU1EYnNjb3JlIGFuZCBhbW91bnQgb2YgbW9uZXkgZ3Jvc3NlZCwgd2UgY2FuIG9ic2VydmUKdGhhdCB0aGVyZSBpc24ndCBtdWNoIG9mIGEgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHJhdGluZyBvZiBhIGZpbG0gKG9yCmhvdyAib2JqZWN0aXZlbHkgZ29vZCIgYSBtb3ZpZSBpcykgYW5kIHRoZSBhbW91bnQgb2YgbW9uZXkgaXQgbWFrZXMuCgpPbiB0aGUgb3RoZXIgaGFuZCwgdG8gaW52ZXN0aWdhdGUgb3BpbmlvbnMgb2YgZmlsbXMgZnJvbSBwcm9mZXNzaW9uYWxzCmFuZCB0cnVzdGVkIG1lbWJlcnMgb2YgdGhlIGZpbG0gaW5kdXN0cnksIHdlIGNhbiB0dXJuIHRvIHRoZSBBY2FkZW15CkF3YXJkcy4KCmBgYHtyLGZpZy53aWR0aD0xMCxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJUaGlzIHNjYXR0ZXIgcGxvdCBkaXNwbGF5cyB0aGUgdG9wIDIwIGhpZ2hlc3QgZ3Jvc3NpbmcgbW92aWVzIG9mIGFsbCB0aW1lIGJ5IHRoZWlyIHByb2ZpdCBhbmQgdGhlIG1haW4gY2hhcmFjdGVyJ3MgcmFjZS4gSXQgc2hvd3MgdGhhdCBvdXQgb2YgMjAgbW92aWVzLCAyIGhhcyBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3Rlci4ifQpmaWcyCmBgYAoKSXQgc2VlbXMgbGlrZSBhIG1vdmllJ3MgcmV2ZW51ZSBpcyBub3QgYSBzdHJvbmcgaW5kaWNhdG9yIGZvciBpdHMKYWNjb2xhZGVzLiBBbW9uZyB0aGUgdG9wIDIwIG1vdmllcyB3aXRoIHRoZSBoaWdoZXN0IHdvcmxkd2lkZSBib3ggb2ZmaWNlCmFuZCB0aGVpciBPc2NhcnMgYXdhcmRzLCBvbmx5IDExIG1vdmllcyBoYWQgYW55IG5vbWluYXRpb25zIGF0IGFsbC4KRnVydGhlcm1vcmUsIHRoaXMgbGlzdCBnZXRzIGV2ZW4gbW9yZSBuYXJyb3dlZCBkb3duIGFzIHdlIGxvb2sgaW50bwp3aW5zL2xvc2VzLiBUaXRhbmljLCBBdmF0YXIsIEJsYWNrIFBhbnRoZXIsIGFuZCBGcm96ZW4gYXJlIHRoZSBvbmx5Cm1vdmllcyBpbiB0aGUgdG9wIDIwIGhpZ2hlc3Qgd29ybGR3aWRlIGdyb3NzaW5nIG1vdmllcyB0byBoYXZlIGhhZCBhdApsZWFzdCBvbmUgbm9taW5hdGlvbiBhbmQgd29uLCB3aXRoIFRpdGFuaWMgYXMgdGhlIG1vc3QgcHJvbGlmaWMgd2l0aCAxMQpvdXQgb2YgMTQgY2F0ZWdvcmllcyAoYWZ0ZXIgZ3JvdXBpbmcgc29tZSBvZiB0aGVtIHRvZ2V0aGVyKS4KClRoZSBPc2NhcnMsIGhvd2V2ZXIsIGFyZSBub3QgYW4gb2JqZWN0aXZlIG1lYW5zIG9mIGF3YXJkc2hpcC4gSW4gMjAxNSwKdGhlIGFjYWRlbXkgImF3YXJkZWQgYWxsIDIwIGFjdGluZyBub21pbmF0aW9ucyB0byB3aGl0ZSBhY3RvcnMgZm9yIHRoZQpmaXJzdCBvZiB0d28gY29uc2VjdXRpdmUgeWVhcnMsIGluc3BpcmluZyBBcHJpbCBSZWlnbiB0byBjcmVhdGUgdGhlCmhhc2h0YWcgI09zY2Fyc1NvV2hpdGUiIFsoVWd3dSwKMjAyMCldKGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjAvMDIvMDYvbW92aWVzL29zY2Fyc3Nvd2hpdGUtaGlzdG9yeS5odG1sKS4KTGVhdmluZyB0aGUgZGV0ZXJtaW5hdGlvbiBvZiBmaWxtIHN1Y2Nlc3MgdG8gdGhlIEFjYWRlbXkgc2VlbXMgdG8geWllbGQKYSBjZWxlYnJhdGlvbiBvZiB3aGl0ZSBjcmVhdG9ycyBhbmQgYXJ0aXN0cywgZXhjbHVkaW5nIGEgd2hvbGUgd29ybGQgb2YKZGl2ZXJzZSBjaW5lbWEuCgpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJUaGlzIHNjYXR0ZXIgcGxvdCBkaXNwbGF5cyB0aGUgdG9wIDIwIGhpZ2hlc3QgZ3Jvc3NpbmcgbW92aWVzIG9mIGFsbCB0aW1lIGJ5IHRoZWlyIHByb2ZpdCBhbmQgdGhlIG1haW4gY2hhcmFjdGVyJ3MgcmFjZS4gSXQgc2hvd3MgdGhhdCBvdXQgb2YgMjAgbW92aWVzLCAyIGhhcyBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3Rlci4ifQpmaWczCmBgYAoKQXMgb2YgMjAyMCwgW2FsbW9zdCBoYWxmIG9mIHRoZSBVLlMuIHBvcHVsYXRpb24gKDQyLjIlKSBhcmUgcGVvcGxlIG9mCmNvbG9yXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SYWNlX2FuZF9ldGhuaWNpdHlfaW5fdGhlX1VuaXRlZF9TdGF0ZXMjOn46dGV4dD1BcyUyMG9mJTIwMjAyMCUyQyUyMFdoaXRlJTIwQW1lcmljYW5zLG1pbm9yaXR5JTJDJTIwbWFraW5nJTIwdXAlMjAxMi4xJTI1KS4KWWV0LCBIb2xseXdvb2QgZmFpbHMgdG8gY29uc2lkZXIgdGhlbSB3aGVuIG1ha2luZyBtb3ZpZXMuIEluIHRoZSB0b3AgMjAKaGlnaGVzdCBncm9zc2luZyBtb3ZpZXMgb2YgYWxsIHRpbWUsIG9ubHkgMiBtb3ZpZXMgZmVhdHVyZWQgYSBub24td2hpdGUKbWFpbiBjaGFyYWN0ZXItLS1ib3RoIG9mIHdoaWNoIHdlcmUgQmxhY2sgbWFsZXMuIE5vbmUgb2YgdGhlc2UgbW92aWVzCmFyZSBpbiB0aGUgdG9wIDUgb2YgdGhpcyBsaXN0IGluIHRlcm1zIG9mIHByb2ZpdCBhbmQgZ3Jvc3Npbmcgd2hpbGUKb3RoZXIgdW5kZXJyZXByZXNlbnRlZCBkZW1vZ3JhcGhpY3MgKExhdGluZXMsIEVhc3QvU291dGgvU291dGhlYXN0CkFzaWFucywgTmF0aXZlIEFtZXJpY2FucywgQWZybyBMYXRpbm9zLCBldGMuKSBhcmUgbGVmdCBjb21wbGV0ZWx5IG9mZgp0aGUgc2NyZWVuLgoKRnVydGhlcm1vcmUsIGluIHRoZSBoaXN0b3J5IG9mIHRoZSBPc2NhcnMgb25seSB0aHJlZSB3b21lbiBoYXZlIHdvbiB0aGUKY292ZXRlZCBiZXN0IGRpcmVjdG9yIHRpdGxlLiBUaGlzIHJlZmxlY3RzIGEgZ2VuZGVyZWQgbWVhc3VyZSBvZiBzdWNjZXNzCndpdGhpbiB0aGUgZmlsbSBpbmR1c3RyeSwgd2hlcmUgbW9zdCBvZiB0aGUgcHJhaXNlIGdvZXMgdG8gZmlsbXMgYWJvdXQKYW5kIGNyZWF0ZWQgYnkgY2lzIG1lbi4gVG8gbWVhc3VyZSB0aGUgcmVwcmVzZW50YXRpb24gb2Ygd29tZW4gaW4gZmlsbXMsCndlIGNhbiB0dXJuIHRvIHRoZSBbQmVjaGRlbCB0ZXN0XShodHRwczovL2JlY2hkZWx0ZXN0LmNvbS8pIHdoaWNoIHdhcwpwb3B1bGFyaXplZCBieSBBbGlzb24gQmVjaGRlbC4gVGhlIHRlc3QgbmFtZXMgdGhyZWUgc2ltcGxlIGNyaXRlcmlhOiAoMSkKaXQgaGFzIHRvIGhhdmUgYXQgbGVhc3QgdHdvIHdvbWVuIGluIGl0LCB3aG8gKDIpIHdobyB0YWxrIHRvIGVhY2ggb3RoZXIsCmFib3V0ICgzKSBzb21ldGhpbmcgYmVzaWRlcyBhIG1hbi4gQWx0aG91Z2ggdGhpcyB0ZXN0IHNlZW1zIGVhc3kgZW5vdWdoLApvbmx5IDI1JSBvZiB0aGUgdG9wIHNjb3JlZCBmaWxtcyBhbmQgNTAlIG9mIHRoZSB0b3AgZ3Jvc3NpbmcgZmlsbXMKcGFzc2VkLiBJbnRlcmVzdGluZ2x5IGVub3VnaCwgd2hlbiBjb21wYXJpbmcgdGhlIHR3byBkYXRhc2V0cyB0byBhbgphdmVyYWdlIEJlY2hkZWwgdGVzdCBzY29yZSBicmVha2Rvd24sIHdlIGNhbiBzZWUgdGhhdCB0aGUgaGlnaGVzdApncm9zc2luZyBmaWxtcyBhbGwgaGF2ZSB3b21lbiBhbmQgYW4gYWJvdmUgYXZlcmFnZSBzY29yZSBvZiAib2siIGFuZAoiZHViaW91cyIuIEhvd2V2ZXIsIHRoZSBoaWdoZXN0IHNjb3JlZCBmaWxtcyBoYXZlIGxlc3MgdGhhbiBhdmVyYWdlICJvayIKYW5kIGR1YmlvdXMiIHNjb3Jlcy4KCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGZpZy5hbHQ9IkEgc3RhY2tlZCBjb2x1bW4gY2hhcnQgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBkaXN0cmlidXRpb24gb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0IGJ5IGRpZmZlcmVudCBtb3ZpZSBzZXRzLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIG1vdmllIHNldHMsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0LiBUaGUgY2hhcnQgaXMgZGl2aWRlZCBpbnRvIGZpdmUgY2F0ZWdvcmllcyBiYXNlZCBvbiB0aGUgQmVjaGRlbCB0ZXN0IHNjb3JlOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB0b29sdGlwIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIG1vdmllcyBmb3IgZWFjaCBjYXRlZ29yeSBhbmQgbW92aWUgc2V0LiJ9CmZpZzQKYGBgCgpUaGUgdHJlbmQgd2UgaGF2ZSBpZGVudGlmaWVkIGhlcmUgaXMgc3Ryb25nOiBtb3ZpZXMgdGhhdCBtYWtlIHRoZSBtb3N0Cm1vbmV5IGFyZSBtb3N0IG9mdGVuIHRoYW4gbm90IHdoaXRlLSwgbWFsZS0sIGFuZCBFdXJvLWNlbnRyaWMuIEV2ZW4KbG9va2luZyBiZXlvbmQgdGhlIGRvbGxhciwgd2UgY2FuIHNlZSBob3cgc2NvcmluZyBzeXN0ZW1zIGFuZCBhd2FyZHMgYXJlCmJpYXNlZCB0b3dhcmRzIHRoaXMgZGVtb2dyYXBoaWMgYXMgd2VsbC4gQWx0aG91Z2ggdGhlIEFtZXJpY2FuIG1vdmllCmluZHVzdHJ5IGNvbnRpbnVlcyBhY2hpZXZlZCBjb21tZXJjaWFsIHN1Y2Nlc3MsIGl0IGhpc3RvcmljYWxseSBoYXMsIGFuZApjb250aW51ZXMgdG8sIGxhY2sgc3VmZmljaWVudCByZXByZXNlbnRhdGlvbi4gV2hpbGUgSG9sbHl3b29kIGhhcwp1bmRvdWJ0ZWRseSBjcmVhdGVkIG5vdGFibGUgZmlsbXMgbGlrZSBUaGUgV2l6YXJkIG9mIE96LCBHb25lIFdpdGggVGhlCldpbmQsIFRoZSBNYXRyaXgsIGFuZCBKdXJhc3NpYyBQYXJrLCB0aGUgaW5kdXN0cnkncyBmb2N1cyBvbiB3aGl0ZSBtYWxlcwpoYXMgcmVzdWx0ZWQgaW4gYSBzaWduaWZpY2FudCBsb3NzIG9mIGRpdmVyc2UgcGVyc3BlY3RpdmVzIGFuZCBjaW5lbWF0aWMKZXhwZXJpZW5jZXMuIEl0IHNlZW1zIGxpa2Ugd2hlbiB3ZSBhcmUgdHJ5aW5nIHRvIGp1ZGdlIGEgbW92aWUsIHdlCnNob3VsZCBoYXZlIGEgYnJvYWRlciByZXBlcnRvaXJlIG9mIG1lYXN1cmVtZW50cyBmb3IgaG93ICpnb29kKiBpdCBpcwpvdGhlciB0aGFuIGp1c3QgbW9uZXkuCgojIERhdGEgRGVzY3JpcHRpb24KCkFsbCBvZiBvdXIgZGF0YXNldHMgd2FzIHNjcmFwZWQgZnJvbSBwdWJsaWMgZG9tYWlucyBzdWNoIGFzCltrYWdnbGUuY29tXShodHRwczovL2thZ2dsZS5jb20vKSBhbmQKW2ZpdmV0aGlydHllaWdodF0oaHR0cHM6Ly9maXZldGhpcnR5ZWlnaHQuY29tLykuIEluIHRvdGFsLCB3ZSB1c2VkIDQKZGF0YXNldHMgdG8gc3VwcG9ydCBvdXIgcmVzZWFyY2ggcGFwZXI6IDxicj4KCjEuICBUaGUgT3NjYXIgQXdhcmQsIFsxOTI3IC0KICAgIDIwMjNdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvdW5hbmltYWQvdGhlLW9zY2FyLWF3YXJkKToKCi0gICAxMCw3NjUgT3NjYXIgbm9taW5hdGlvbnMKLSAgIHNjcmFwZWQgZnJvbSB0aGUgT2ZmaWNpYWwgQWNhZGVteSBBd2FyZHMKLSAgIDcgdmFyaWFibGVzOiB5ZWFyLCBuYW1lLCBmaWxtLCBjYXRlZ29yaWVzLCB3aW4sLi4uIDxicj4KCjIuICBNb3ZpZSBJbmR1c3RyeTogRm91ciBkZWNhZGVzIG9mIG1vdmllcywKICAgIFsxOTg2LTIwMTZdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvZGFuaWVsZ3JpamFsdmFzL21vdmllcyk6CgotICAgNjgyMCBtb3ZpZXMgaW4gdGhlIGRhdGFzZXQgKGFyb3VuZCAyMjAgbW92aWVzIHBlciB5ZWFyKQotICAgMTUgdmFyaWFibGVzOiBidWRnZXQsIGNvbXBhbnksIGNvdW50cnksIGRpcmVjdG9yLCBnZW5yZSwgbmFtZSwuLi4uCiAgICA8YnI+CgozLiAgQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2UsCiAgICBbMTkzOS0yMDIxXShodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2traGFuZGVrYXIvYWxsLXRpbWUtd29ybGR3aWRlLWJveC1vZmZpY2UpCgotICAgY29udGFpbnMgdGhlIHRvcCBtb3ZpZXMgYmFzZWQgb24gdGhlIGN1bXVsYXRpdmUgd29ybGR3aWRlIGJveCBvZmZpY2UKLSAgIDc1MTIgbW92aWVzIGFuZCA2IHZhcmlhYmxlczogcmFuaywgd29ybGR3aWRlLWludGVybmF0aW9uYWwtZG9tZXN0aWMKICAgIGJveCBvZmZpY2UsLi4uIDxicj4KCjQuICBCZWNoZGVsIFRlc3QsIDE5NzAtMjAxMyAoZnJvbSBsaWJyYXJ5KGZpdmV0aGlydHllaWdodCkpCgotICAgdGVzdHMgd2hldGhlciBtb3ZpZXMgbWVldCB0aGUgZm9sbG93aW5nIGNyaXRlcmlhOiBUaGVyZSBhcmUg4omlIDIKICAgIChuYW1lZCkgZmVtYWxlIGNoYXJhY3RlcnM7dGhlc2Ugd29tZW4gdGFsayB0byBlYWNoIG90aGU7IGFib3V0CiAgICBzb21ldGhpbmcgb3RoZXIgdGhhbiBhIG1hbi4KLSAgIDE3OTQgbW92aWVzLCAxNSB2YXJpYWJsZXM6IG1vdmllLCByZXN1bHQsIGdyb3NzaW5ncywgLi4uCgojIExpbWl0YXRpb25zCgojIyBEYXRhCgpUaGVyZSBhcmUgc29tZSBsaW1pdGF0aW9ucyBpbiB0aGUgZGF0YXNldHMuIEZpcnN0bW9zdCwgd2hlbiBjb21wYXJpbmcKdGhlIHdvcmxkd2lkZSBncm9zc2luZyBhbW91bnQgb2YgbW92aWVzLCB3ZSB3ZXJlIHVuYWJsZSB0byBhY2NvdW50IGZvcgppbmZsYXRpb24uIFRoZSBkYXRhc2V0ICJBbGwgVGltZSBXb3JsZHdpZGUgQm94IE9mZmljZSIgc2NyYXBlZCB0aGUgdGhlCmFtb3VudHMgb2YgaW50ZXJuYXRpb25hbCBncm9zc2luZyBmcm9tIDE5MzkgdG8gMjAyMSwgYnV0IElNRGIgc3RhdGVzCnRoYXQgWyJhbGwgZmlndXJlcyBhcmUgbm90IGFkanVzdGVkIGZvcgppbmZsYXRpb24iXShodHRwczovL2hlbHAuaW1kYi5jb20vYXJ0aWNsZS9jb250cmlidXRpb24vdGl0bGVzL2J1c2luZXNzLWltZGJwcm8tb25seS9HRUpVV1NCQjZXWEgzUlo2IykuCjxicj4gQWNjb3JkaW5nIHRvIGEgTWlubmVzb3RhbiBpbmZsYXRpb24gY2FsY3VsYXRvciBbMSBVLlMuIERvbGxhciBpbgoxOTM5IGlzIHdvcnRoIFwkMTkuNDgKdG9kYXldKGh0dHBzOi8vd3d3Lm1pbm5lYXBvbGlzZmVkLm9yZy9hYm91dC11cy9tb25ldGFyeS1wb2xpY3kvaW5mbGF0aW9uLWNhbGN1bGF0b3IpLAp3aGljaCBtZWFucyB0aGF0IHRoZSBhbW91bnQgb2YgbW9uZXkgb2NjdXJyaW5nIGluIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMKaXMgbm90IHNjYWxlZCB0byBzaXplLiBBZGRpdGlvbmFsbHksIGluIHRoZSBkYXRhc2V0IHVzZWQgZm9yIHRoZSByYWNpYWwKZGlzdHJpYnV0aW9uIG9mIE9zY2FycyB3aW5uZXJzLCB0aGUgZGF0YXNldCBvbmx5IGNvbnRhaW5lZCB0aGUgcmFjaWFsCmlkZW50aXRpZXMgb2YgYmVzdCBkaXJlY3RvcnMsIGFjdG9ycywgYW5kIGFjdHJlc3Nlcy4gVGhpcyBleGNsdWRlcyAyMQpvdGhlciBhd2FyZCBjYXRlZ29yaWVzLCB3aGljaCBjb3VsZCBoYXZlIGdpdmVuIG1vcmUgYWNjdXJhdGUgaW5zaWdodAppbnRvIHRoZSBkZW1vZ3JhcGhpY3Mgb2YgT3NjYXJzIHdpbm5lcnMgYWNyb3NzIHRoZSBlbnRpcmUgYXdhcmQKY2VyZW1vbnkuXAo8YnI+IEZ1cnRoZXJtb3JlLCB3ZSB1c2VkIElNRGIgcmF0aW5ncyB0byBpbnZlc3RpZ2F0ZSBob3cgbW92aWVzIG9mCnZhcmlvdXMgZ3Jvc3NpbmcgYW1vdW50cyBhcmUgc2NvcmVkLCBidXQgaXQgaXMgd29ydGggbm90aW5nIHRoYXQgdGhlCndlYnNpdGUgY2FsY3VsYXRlcyBhbiBvdmVyYWxsIHNjb3JlIGZyb20gcmVnaXN0ZXJlZCB1c2VycyBjYXN0aW5nIHRoZWlyCnZvdGVzLiBIb3dldmVyLCB0aGVyZSBoYXMgYmVlbiBhIGxhcmdlciBkaXNjdXNzaW9uIGFyb3VuZCB0aGUKbWV0aG9kb2xvZ3kgb2YgdGhpcyBzeXN0ZW0gb2YgbW92aWUtcmF0aW5nLCB3aXRoIHNvbWUgcGVvcGxlIGRlZW1pbmcKb25saW5lIG1vdmllIHZvdGluZyBzeXN0ZW1zIHRvIGJlIGluZWZmZWN0aXZlLiBBZGRpdGlvbmFsbHksIGl0IHdhcwpmb3VuZCB0aGF0ICJtb3N0IElNRGIgdm90ZXJzIGFyZSBtYWxlLCB3aGljaCBzZWVtcyB0byBza2V3IHRoZSByYW5raW5nCmluIGZhdm91ciBvZiBmaWxtcyB0aGF0IGFyZSBhaW1lZCBtb3JlIHRvd2FyZHMgbWVuIiBbKFJleW5vbGRzLAoyMDE3KV0oaHR0cHM6Ly93d3cud2lyZWQuY28udWsvYXJ0aWNsZS93aGljaC1maWxtLXJhbmtpbmctc2l0ZS1zaG91bGQtaS10cnVzdC1yb3R0ZW4tdG9tYXRvZXMtaW1kYi1tZXRhY3JpdGljKS4KSXQgaXMgd29ydGggYWNrbm93bGVkZ2luZyB0aGF0IElNRGIgcmF0aW5ncyBhcmUgYSBiaWFzZWQgc3lzdGVtIG9mCnJhbmtpbmcgYSBmaWxtLCBob3dldmVyLCB0aGlzIGZ1cnRoZXIgYWlkcyBvdXIgcmVzZWFyY2ggcXVlc3Rpb24gaW4KaWxsdXN0cmF0aW5nIHRoZSBjb21wbGljYXRpb25zIHRoYXQgY29tZSB3aXRoIGRldGVybWluaW5nIHdoZXRoZXIgYQptb3ZpZSBpcyAiZ29vZCIuIDxicj4gQW5vdGhlciBsaW1pdGF0aW9uIG9mIHRoaXMgcHJvamVjdCBpcyB1c2luZyBUaGUKQmVjaGRlbCB0ZXN0IGFzIGEgbWVhc3VyZSBvZiBnZW5kZXIgZXF1YWxpdHkgaW4gZmlsbS4gVGhlIEJlY2hkZWwgdGVzdAppcyBhbiBpbmZhbW91cyBtZWFzdXJlIG9mIEhvbGx5d29vZCdzIGdlbmRlciBpbWJhbGFuY2UsIGhvd2V2ZXIgaXQgaXMgYW4Kb3ZlcnNpbXBsaWZpZWQgbWVhbnMgb2YgYW5hbHl6aW5nIHRoZSByb2xlIG9mIHdvbWVuIGluIGZpbG0uIEl0IGFza3MKdGhyZWUgcXVlc3Rpb25zIG9mIGEgbW92aWUsIGFuZCB3aGlsZSBhc3RvbmlzaGluZ2x5IG1hbnkgZmlsbXMgZG8gbm90CnBhc3MgdGhhdCBiYXIsIHRoZSBzaW1wbGljaXR5IG9mIHRoaXMgdGVzdCAiZG9lc24ndCBhZGRyZXNzIHRoZSBjb3JlCmluZXF1YWxpdGllcyBpbiBIb2xseXdvb2QgZmlsbXMiIFsoSGlja2V5IGV0IGFsLAoyMDE3KV0oaHR0cHM6Ly9wcm9qZWN0cy5maXZldGhpcnR5ZWlnaHQuY29tL25leHQtYmVjaGRlbC8pLiBJbiB0aGUKZGF0YXNldCB3ZSB1c2VkLCB0aGVyZSB3ZXJlIG1hbnkgaW5zdGFuY2VzIG9mICJkdWJpb3VzIiB3aGVyZSB0aGUgcm9sZQpvZiB3b21lbiBpbiB0aGUgZmlsbSB3ZXJlIGRlYmF0ZWQsIGFuZCB0aGVyZWZvcmUsIHRoZSBwYXNzL2ZhaWwgc2NvcmUKY291bGRuJ3QgYmUgZGV0ZXJtaW5lZC4gVG8gY3JlYXRlIGEgbW9yZSBob2xpc3RpYyBhbmFseXNpcyBvZiBnZW5kZXIKZXF1YWxpdHkgaW4gSG9sbHl3b29kIGluIHRoZSBmdXR1cmUsIGl0IGlzIHdvcnRoIHJlc2VhcmNoaW5nIG5ldyB0ZXN0cwp0aGF0IGluY2x1ZGUgbm9uLWJpbmFyeSBwZW9wbGUsIGFuZCBleHBhbmQgdGhlIHJlcXVpcmVtZW50cy4gRm9yIGlkZWFzLAp3ZSBjYW4gdHVybiB0byAiV2UgcGl0dGVkIDUwIG1vdmllcyBhZ2FpbnN0IDEyIG5ldyB3YXlzIG9mIG1lYXN1cmluZwpIb2xseXdvb2QncyBnZW5kZXIgaW1iYWxhbmNlIiB3aGljaCBzdWdnZXN0cyBuZXcgdGVzdHMgdGhhdCBsb29rIGJleW9uZAp3aGl0ZSB3b21lbiwgYW5kIHRoZSBjYXN0IGFuZCBjcmV3IG9mIHRoZSBmaWxtLgoKIyMgVmlzdWFsaXphdGlvbnMvIE92ZXJhbGwgUmVzZWFyY2gKCk91ciBhdHRlbXB0IHRocm91Z2hvdXQgdGhpcyByZXNlYXJjaCBpcyB0byBzdWdnZXN0IGRpZmZlcmVudCBtZXRyaWNzIHRvCmNvbXBhcmUgYW5kIGNvbmNsdWRlIGEgbW92aWUgcXVhbGl0eSBhbmQgcHVibGljIHBlcmZvcm1hbmNlIG90aGVyIHRoYW4KaXRzIHJldmVudWUgYW5kIHByb2ZpdCByZXR1cm5zLiBEZXNwaXRlIHRoZSB2YXJpb3VzIGluZGljYXRvcnMgd2UgaGF2ZQppbmNsdWRlZCB0byBvZmZlciBvdGhlciBhdmVudWVzIGluIGRldGVybWluaW5nIGEgZ29vZCBtb3ZpZSwgb3VyICJ0ZXN0cyIKYXJlIHNpbXBseSBub3QgZW5vdWdoLiBXaXRoIHRoZSBsaW1pdGVkIHNjb3BlIG9mIGF2YWlsYWJsZSBhbmQgInBlcmZlY3QiCmRhdGEsIG91ciByZXNlYXJjaCBmYWNlIHJlYWwgd29ybGQgbGltaXRhdGlvbnMgdGhhdCBmYWlsIHRvIGFzY2VydGFpbgp0aGUgc2V2ZXJpdHkgYW5kIGFycmF5IG9mIEhvbGx5d29vZCdzIGluZXF1YWxpdGllcyB0aGF0IGFyZSBiZXlvbmQgdGhlCndoaXRlIG1hbGUgcG9wdWxhdGlvbi4gSXQgYWxzbyBsZWF2ZXMgb3V0IHRoZSBwb3B1bGF0aW9uIHRoYXQgc3RhbmRzCmJlaGluZCB0aGUgY2FtZXJhIGluIG1vdmllIHByb2R1Y3Rpb24gc3VjaCBhcyBzY3JlZW53cml0ZXJzLCBwcm9kdWNlcnMsCnNldCBkZXNpZ25lcnMsIGV0Yy4gQWxsIG9mIHRoZXNlIGFyZSwgaGVuY2UsIHJlZmxlY3RlZCBpbiBvdXIKdmlzdWFsaXphdGlvbnMuIEhvd2V2ZXIsIHdlIGhvcGUgdGhhdCBvdXIgcmVzZWFyY2ggY2FuIHNlcnZlIGFzIGFuCmluY2VudGl2ZSBmb3IgdGhlIGZpbG0gaW5kdXN0cnkgYXMgd2VsbCBhcyBpdHMgYXVkaWVuY2UgdG8gYmUgbW9yZQpjcml0aWNhbCBvZiBtb3ZpZXMgYW5kIG1vdmllIG1ha2luZy4KCiMgQ29kZSBBcHBlbmRpeAoKYGBge3IsIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNwbGl0c3RhY2tzaGFwZSkKbGlicmFyeShkYnBseXIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShyZWFkcikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdndGhlbWVzKQpsaWJyYXJ5KGZpdmV0aGlydHllaWdodCkKbGlicmFyeShoaWdoY2hhcnRlcikKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocnZlc3QpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnYXBtaW5kZXIpCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShtYWdyaXR0cikKCgojTG9hZGluZyByYXcgZGF0YQpib3hfb2ZmaWNlIDwtcmVhZF9jc3YoIkFsbCBUaW1lIFdvcmxkd2lkZSBCb3ggT2ZmaWNlLmNzdiIpCm1vdmllc19pbmZvIDwtIHJlYWRfY3N2KCJtb3ZpZXMuY3N2IikKb3NjYXJzX2F3YXJkIDwtIHJlYWRfY3N2KCJ0aGVfb3NjYXJfYXdhcmQuY3N2IikKYmVjaGRlbCA8LSBkYXRhLmZyYW1lKGJlY2hkZWwpCmJlY2hkZWxzZXQgPC0gcmVhZF9jc3YoImJlY2hkZWxzZXQuY3N2IikKQmVjaGRlbG1vbmV5IDwtIHJlYWRfY3N2KCJCZWNoZGVsbW9uZXkuY3N2IikKYmlvcGljcyA8LSBkYXRhLmZyYW1lKGJpb3BpY3MpClJhdGluZ0dyb3NzIDwtIHJlYWRfY3N2KCJSYXRpbmdHcm9zc19lZGl0Mi5jc3YiKQoKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDEKI2F2ZXJhZ2UgZ3Jvc3NpbmcgZm9yIGVhY2ggdG9wIDIwIHNjb3JlZAoKdG9wX3Njb3JlIDwtIG1vdmllc19pbmZvICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUsIHllYXIsIGdyb3NzKSAlPiUgCiAgYXJyYW5nZShkZXNjKHNjb3JlKSkKCiNhdmVyYWdlIGdyb3NzaW5nIGZvciBlYWNoIHRvcCAyMCBzY29yZWQKCmxvd19zY29yZSA8LSBtb3ZpZXNfaW5mbyAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLCB5ZWFyLCBncm9zcykgJT4lIAogIGFycmFuZ2Uoc2NvcmUpCgoKCm9zY2Fyd2lucyA8LSAgbW92aWVzX2luZm8gJT4lIAogIGZpbHRlcihuYW1lICVpbiUgYygiVGhlIExvcmQgb2YgdGhlIFJpbmdzOiBUaGUgUmV0dXJuIG9mIHRoZSBLaW5nIiwgIlRpdGFuaWMiLCAiQmVuLUh1ciIsICJXZXN0IFNpZGUgU3RvcnkiLCAiVGhlIEVuZ2xpc2ggUGF0aWVudCIsICJUaGUgTGFzdCBFbXBlcm9yIiwgIkdpZ2kiLCAiU2x1bWRvZyBNaWxsaW9uYWlyZSIsICJBbWFkZXVzIiwgIkdhbmRoaSIpKSAlPiUgCiBzdW1tYXJpemUoc3VtPXN1bShncm9zcykpCgptb3ZpZXNfaW5mbyAlPiUKICBncm91cF9ieSh5ZWFyKSAlPiUKICBzdW1tYXJpemUodG90YWxfbW92aWVzID0gbigpLAogICAgICAgICAgICBhbWVyaWNhbl9tb3ZpZXMgPSBzdW0oY291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyIpLAogICAgICAgICAgICBwZXJjZW50X2FtZXJpY2FuID0gMTAwICogYW1lcmljYW5fbW92aWVzIC8gdG90YWxfbW92aWVzKQoKCmRvdWJsZWRhdGEgPC0gbW92aWVzX2luZm8gJT4lCiAgbGVmdF9qb2luKFJhdGluZ0dyb3NzLAogICAgYnkgPSBjKCJuYW1lIiwgInllYXIiID0gIlllYXIiKSkKCgp0b3Bncm9zcyA8LSBkb3VibGVkYXRhICU+JSAKICBmaWx0ZXIoZG91YmxlZGF0YSRSYW5rIDwgMjUpICU+JSAgCiAgYXJyYW5nZShkZXNjKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkpICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgUmFuaywgYFdvcmxkd2lkZUJveCBPZmZpY2VgKQoKZHVwbGljYXRlX3Jvd3MgPC0gdG9wZ3Jvc3NbZHVwbGljYXRlZCh0b3Bncm9zcyksIF0KdG9wZ3Jvc3MgPC0gdW5pcXVlKHRvcGdyb3NzKQoKCnRvcHJhdGUgPC0gZG91YmxlZGF0YSAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLngsIFJhbmssIGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkgJT4lIAogIGFycmFuZ2UoZGVzYyhzY29yZS54KSkgCgogICAgIAp0b3Bncm9zc18yMCA8LSBoZWFkKHRvcGdyb3NzLCBuID0gMjApICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgYFdvcmxkd2lkZUJveCBPZmZpY2VgKQp0b3BzY29yZV8yMCA8LSBoZWFkKHRvcHJhdGUsIG4gPSAyMCkgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBgV29ybGR3aWRlQm94IE9mZmljZWApCgoKCmBgYAoKYGBge3IsZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0RhdGEgY2xlYW5pbmcgZm9yIGZpZ3VyZSAyCiMgQ2hhbmdpbmcgQm94IE9mZmljZSB2YXJpYWJsZXMgaW50byBudW1lcmljYWwgdmFsdWVzCmJveF9vZmZpY2UgPC1ib3hfb2ZmaWNlICU+JSAKIG11dGF0ZShgV29ybGR3aWRlQm94IE9mZmljZWA9YXMubnVtZXJpYyhzdHJfcmVwbGFjZV9hbGwoYFdvcmxkd2lkZUJveCBPZmZpY2VgLCJbJCxdIiwiIikpKSAlPiUgCiAgbXV0YXRlKGBEb21lc3RpY0JveCBPZmZpY2VgPWFzLm51bWVyaWMoc3RyX3JlcGxhY2VfYWxsKGBEb21lc3RpY0JveCBPZmZpY2VgLCJbJCxdIiwiIikpKSAlPiUKICBtdXRhdGUoYEludGVybmF0aW9uYWxCb3ggT2ZmaWNlYD1hcy5udW1lcmljKHN0cl9yZXBsYWNlX2FsbChgSW50ZXJuYXRpb25hbEJveCBPZmZpY2VgLCJbJCxdIiwiIikpKQoKI0dldHRpbmcgdGhlIFRvcCAyMCBCb3ggT2ZmaWNlCmJveF9vZmZpY2VfdG9wMjAgPC0gYm94X29mZmljZSAlPiUgIAogIGFycmFuZ2UoUmFuaykgJT4lIAogIGhlYWQoMjApICU+JSAKICBtdXRhdGUoTW92aWU9aWZlbHNlKE1vdmllPT0iSGFycnkgUG90dGVyIGFuZCB0aGUgRGVhdGhseSBIYWxsb3dzOuKApiIsICJIYXJyeSBQb3R0ZXIgYW5kIHRoZSBEZWF0aGx5IEhhbGxvd3M6IFBhcnQgMiIsTW92aWUpKQoKCiNDcmVhdGluZyBPc2NhciBjYXRlZ29yeSBkYXRhIGZyYW1lCm9zY2Fyc19jYXRlZ29yeSA8LSB0aWJibGUoCmxldmVscyhmYWN0b3Iob3NjYXJzX2F3YXJkJGNhdGVnb3J5KSkpCiAgCgpvc2NhcnNfY2F0ZWdvcnkgPC0gb3NjYXJzX2NhdGVnb3J5ICU+JSAKICByZW5hbWUoImNhdGVnb3J5Ij0ibGV2ZWxzKGZhY3Rvcihvc2NhcnNfYXdhcmQkY2F0ZWdvcnkpKSIpIAogIAoKb3NjYXJzX2NhdGVnb3J5IDwtIG9zY2Fyc19jYXRlZ29yeSAlPiUgCiAgbXV0YXRlKGJyb2FkX2NhdGVnb3J5PXdvcmQoY2F0ZWdvcnksMSkpICU+JSAKICBtdXRhdGUoYnJvYWRfY2F0ZWdvcnk9CiAgICAgICAgICAgY2FzZV93aGVuKGJyb2FkX2NhdGVnb3J5ID09IkFSVCIgfiJBUlQgRElSRUNUSU9OIiwKICAgICAgICAgICAgICAgICAgICAgYnJvYWRfY2F0ZWdvcnkgPT0gIkJFU1QiIH4gIkJFU1QgUElDVFVSRSIsCiAgICAgICAgICAgICAgICAgICAgIGJyb2FkX2NhdGVnb3J5ID09ICJGSUxNIiB+ICJGSUxNIEVESVRJTkciLAogICAgICAgICAgICAgICAgICAgICBicm9hZF9jYXRlZ29yeSA9PSAiQUNUT1IiIHwgYnJvYWRfY2F0ZWdvcnk9PSJBQ1RSRVNTIiB+ICJBQ1RJTkciLAogICAgICAgICAgICAgICAgICAgIFRSVUUgfiBicm9hZF9jYXRlZ29yeSkKICAgICAgICAgICAgKSAKCiNUb3AgMjAgQm94IE9mZmljZSBNb3ZpZXMgYW5kIGF3YXJkcyBkYXRhc2V0IGJ5IGpvaW5pbmcgZGF0YWZyYW1lcwpib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyA8LSBib3hfb2ZmaWNlX3RvcDIwICU+JSAKICBpbm5lcl9qb2luKG9zY2Fyc19hd2FyZCxieT1jKCJNb3ZpZSI9ImZpbG0iKSkgJT4lIAogIGZpbHRlcihZZWFyID09IHllYXJfZmlsbSkgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2NhdGVnb3J5KSAgCgpib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyA8LSBib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyAlPiUgZ3JvdXBfYnkoTW92aWUseWVhcl9maWxtKSAlPiUgCiAgc3VtbWFyaXplKHRvdGFsPW4oKSkgJT4lICBpbm5lcl9qb2luKG9zY2Fyc19hd2FyZCxieT1jKCJNb3ZpZSI9ImZpbG0iKSkgJT4lIAogIGZpbHRlcih5ZWFyX2ZpbG0ueCA9PSB5ZWFyX2ZpbG0ueSkgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2NhdGVnb3J5KSAgJT4lIAogIHNlbGVjdChNb3ZpZSwgeWVhcl9maWxtLngsdG90YWwseWVhcl9jZXJlbW9ueSxuYW1lLHdpbm5lcixicm9hZF9jYXRlZ29yeSkKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDMKI0NoYW5naW5nIG1vdmllIG5hbWVzIHNvIHRoZXkgbWF0Y2ggYWNyb3NzIG1vdmllc19pbmZvIGFuZCBib3hfb2ZmaWNlX3RvcDIwCgptb3ZpZXNfaW5mbyA8LSBtb3ZpZXNfaW5mbyAlPiUgIG11dGF0ZShuYW1lPWNhc2Vfd2hlbigKICBuYW1lPT0iU3RhciBXYXJzOiBFcGlzb2RlIFZJSSAtIFRoZSBGb3JjZSBBd2FrZW5zIiB+ICJTdGFyIFdhcnMgRXAuIFZJSTogVGhlIEZvcmNlIEF3YWtlbnMiLAogIG5hbWUgPT0iU3RhciBXYXJzOiBFcGlzb2RlIFZJSUkgLSBUaGUgTGFzdCBKZWRpIiB+ICJTdGFyIFdhcnMgRXAuIFZJSUk6IFRoZSBMYXN0IEplZGkiLApUUlVFfm5hbWUpKSAlPiUgCiAgbXV0YXRlKGNvbXBhbnk9Y2FzZV93aGVuKAogICAgY29tcGFueT09IldhbHQgRGlzbmV5IEFuaW1hdGlvbiBTdHVkaW9zIiB8IGNvbXBhbnk9PSJXYWx0IERpc25leSBQaWN0dXJlcyIgfiJXYWx0IERpc25leSIsClRSVUV+Y29tcGFueSkpCgojSm9pbmluaW5nIG1vdmllc19pbmZvIGFuZCBib3hfb2ZmaWNlX3RvcDIwCgpib3hfb2ZmaWNlX3RvcDIwX2luZm88LSBib3hfb2ZmaWNlX3RvcDIwICU+JQogIGlubmVyX2pvaW4obW92aWVzX2luZm8sYnk9YygiTW92aWUiPSJuYW1lIiwiWWVhciI9InllYXIiKSkKCiNNYWtpbmcgdG9wMjAgbWFpbiBjaGFyYWN0ZXIncyByYWNlIGRhdGEgZnJhbWUKdG9wMjBfcmFjZSA8LSBkYXRhLmZyYW1lKHN0YXI9Ym94X29mZmljZV90b3AyMF9pbmZvJHN0YXIsUmFjZT1jKCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJCbGFjayIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiQmxhY2siLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIikpCgojSm9pbmluZyBib3hfb2ZmaWNlX3RvcDIwX2luZm8gd2l0aCB0b3AyMF9yYWNlIGRhdGFmcmFtZQpib3hfb2ZmaWNlX3RvcDIwX2luZm8gPC0gYm94X29mZmljZV90b3AyMF9pbmZvICU+JSBkYXRhLmZyYW1lKHRvcDIwX3JhY2UpICU+JSBzZWxlY3QoIXN0YXIuMSkKCmBgYAoKYGBge3IsZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0RhdGEgY2xlYW5pbmcgZm9yIGZpZ3VyZSA0CgpiZWNoZGVsc2V0IDwtIGJlY2hkZWxzZXQgJT4lIAogIG11dGF0ZShzZXRfZmFjdG9yID0gZmFjdG9yKHNldCkpIAoKYmVjaGRlbHNldGF2IDwtIGJlY2hkZWxzZXQgJT4lIAogIGdyb3VwX2J5KHNldF9mYWN0b3IsIGNsZWFuX3Rlc3QpICU+JSAKICBzdW1tYXJpemUoY291bnQgPSBuICgpKQoKYmVjaGRlbHNldGF2IDwtIGJlY2hkZWxzZXRhdiAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC8gMjAgKiAxMDApCgpiZWNoZGVsYXYgPC0gYmVjaGRlbCAlPiUgCiAgZ3JvdXBfYnkoY2xlYW5fdGVzdCkgJT4lICAKICBzdW1tYXJpemUgKGNvdW50ID0gbiAoKSkKCmJlY2hkZWxhdiA8LSBiZWNoZGVsYXYgJT4lICAKICAgIG11dGF0ZShwZXJjZW50ID0gcm91bmQoY291bnQvIDE3OTQgKiAxMDApKSAlPiUgCiAgICBtdXRhdGUoc2V0X2ZhY3RvciA9ICJBdmVyYWdlIEJlY2hkZWwgU2NvcmVzIikKCmpvaW50YXYgPC0gcmJpbmQoYmVjaGRlbHNldGF2LCBiZWNoZGVsYXYpIAoKCmpvaW50YXYkY2xlYW5fdGVzdCA8LSBmYWN0b3Ioam9pbnRhdiRjbGVhbl90ZXN0LCBsZXZlbHMgPSBjKCJub3dvbWVuIiwgIm5vdGFsayIsICJtZW4iLCAiZHViaW91cyIsICJvayIpKQoKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbHQ9IkEgc2NhdHRlciBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBJTURiIHNjb3JlIGFuZCB3b3JsZHdpZGUgYm94IG9mZmljZSBncm9zcyBmb3IgbW92aWVzIHdpdGggZGlmZmVyZW50IEJlY2hkZWwgdGVzdCBzY29yZXMuIEVhY2ggcG9pbnQgcmVwcmVzZW50cyBhIG1vdmllIGFuZCBpcyBjb2xvcmVkIGJhc2VkIG9uIGl0cyBCZWNoZGVsIHRlc3Qgc2NvcmUuIFRoZSBsZWdlbmQgc2hvd3MgdGhlIGZpdmUgQmVjaGRlbCB0ZXN0IHNjb3Jlczogbm8gd29tZW4sIG5vIHRhbGssIG1lbiwgZHViaW91cywgYW5kIG9rLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIElNRGIgc2NvcmUsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHdvcmxkd2lkZSBib3ggb2ZmaWNlIGdyb3NzIGluIG1pbGxpb25zLyBiaWxsaW9ucyBvZiBkb2xsYXJzLiBUaGUgdG9vbHRpcCBkaXNwbGF5cyB0aGUgbW92aWUgbmFtZSwgSU1EYiBzY29yZSwgYW5kIHdvcmxkd2lkZSBncm9zc2luZyBmb3IgZWFjaCBwb2ludC4ifQojRmlndXJlIDEKY29sb3JzIDwtIGMoIiNBQzI1MjgiLCAiI0U0NzkyQyIsICIjNzY0NDg0IiwgIiMzNDY0OTEiLCAiIzQ0ODc0NiIpCgpmaWcxPC1wbG90X2x5KGJlY2hkZWxzZXQsIHggPSB+c2NvcmUueCwgeSA9IH5gV29ybGR3aWRlQm94IE9mZmljZWAsIGNvbG9yID0gfmNsZWFuX3Rlc3QsIGNvbG9ycyA9IGNvbG9ycywgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdtYXJrZXJzJywKICBob3ZlcmluZm8gPSAndGV4dCcsCiAgdGV4dCA9IH5wYXN0ZSgnPC9icj4nLCBuYW1lLCAKICAgICAgICAgICAgICAgICc8L2JyPicsICJJTURCIFNjb3JlOiIsIHNjb3JlLngsIAogICAgICAgICAgICAgICAgJzwvYnI+JywgIldvcmxkd2lkZSBHcm9zc2luZzoiLCBjb21tYShgV29ybGR3aWRlQm94IE9mZmljZWApKSkgJT4lIAogIGxheW91dCh0aXRsZSA9ICdJTURCIFNjb3JlIHZzLiBBbW91bnQgb2YgTW9uZXkgR3Jvc3NlZCcsIAogICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAnSU1EQiBTY29yZScpLCAKICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJ1dvcmxkd2lkZSBCb3ggT2ZmaWNlJyksIAogICAgICAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAiQmVjaGRlbCBUZXN0IFNjb3JlIiksCiAgICAgICAgICAgICAgICAgICAgICAgdGl0bGVzID0gbGlzdCh0b3Bncm9zc18yMCA9ICJUb3AgMjAgR3Jvc3NpbmciLCB0b3BzY29yZV8yMCA9ICJUb3AgMjAgU2NvcmVkIikpKQoKCgoKYGBgCgpgYGB7cixmaWcud2lkdGg9MTAsZmlnLmhlaWdodD02LGZpZy5hbHQ9IlRoaXMgYmFyIGdyYXBoIHNob3dzIHRoZSB0b3RhbCBudW1iZXIgb2Ygb3NjYXIgYXdhcmRzIG5vbWluYXRpb25zIG9mIHRoZSB0b3AgMjAgbW92aWVzIHdpdGggdGhlIGhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UgYnkgQ2F0ZWdvcnkgYW5kIFdpbnMiLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNGaWd1cmUgMgoKZmlnMjwtYm94X29mZmljZV90b3AyMF9hd2FyZHMgJT4lIAogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKE1vdmllLCB0b3RhbCwuZnVuPXN1bSksYWxwaGE9d2lubmVyLGZpbGw9ZmN0X3Jlb3JkZXIoYnJvYWRfY2F0ZWdvcnksd2lubmVyKSkpICsgCiAgZ2VvbV9iYXIoKSsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkrCiAgY29vcmRfZmxpcCgpKwogIGxhYnMoeT0iVG90YWwgTm9taW5hdGlvbnMiLHg9Ik1vdmllIix0aXRsZT0iVG9wIDIwIE1vdmllcyB3aXRoIEhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UgdnMgT3NjYXJzIEF3YXJkcyIsc3VidGl0bGUgPSAiQnkgQ2F0ZWdvcnkgYW5kIFdpbnMiLGZpbGw9IkNhdGVnb3J5IixhbHBoYT0iV2lubmVyIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkIixzaXplPTE2KSxwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSxheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCgoKYGBgCgpgYGB7cixmaWcud2lkdGg9NixmaWcuaGVpZ2h0PTQsZmlnLmFsdD0iVGhpcyBzY2F0dGVyIHBsb3QgZGlzcGxheXMgdGhlIHRvcCAyMCBoaWdoZXN0IGdyb3NzaW5nIG1vdmllcyBvZiBhbGwgdGltZSBieSB0aGVpciBwcm9maXQgYW5kIHRoZSBtYWluIGNoYXJhY3RlcidzIHJhY2UuIEl0IHNob3dzIHRoYXQgb3V0IG9mIDIwIG1vdmllcywgMiBoYXMgYSBub24td2hpdGUgbWFpbiBjaGFyYWN0ZXIuIixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRmlndXJlIDMKZmlnMzwtYm94X29mZmljZV90b3AyMF9pbmZvICU+JSAKICBtdXRhdGUoUHJvZml0PWdyb3NzLWJ1ZGdldCkgJT4lCiAgZ2dwbG90KGFlcyh4PWJ1ZGdldCx5PWdyb3NzLGNvbG9yPVJhY2Usc2l6ZT1Qcm9maXQpKSArCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX21pbmltYWwoKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfY29tbWEoKSkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX2NvbW1hKCkpKwogIHNjYWxlX3NpemVfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9jb21tYSgpKSsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uPSJFIikrCiAgbGFicyh5PSJUb3RhbCBHcm9zcyIseD0iQnVkZ2V0Iix0aXRsZT0iVG9wIDIwIE1vdmllcyB3aXRoIEhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UiLHN1YnRpdGxlID0gIkJ5IFByb2ZpdCBhbmQgUmFjZSBvZiBNYWluIENoYXJhY3RlciIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsc2l6ZT0xMikscGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTgpKSsKICBhbm5vdGF0ZSgidGV4dCIseD0yMDAwMDAwMDAseT0xNDMwMDAwMDAwLGxhYmVsPSJCbGFjayBQYW50aGVyIixzaXplPTMsY29sb3I9InJlZDMiKSsKICAgYW5ub3RhdGUoInRleHQiLHg9MjYwMDAwMDAwLHk9MTc1MDAwMDAwMCxsYWJlbD0iVGhlIExpb24gS2luZyAoMjAxOSkiLHNpemU9Myxjb2xvcj0icmVkMyIpCgogIApgYGAKCmBgYHtyLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsZmlnLmFsdD0iQSBzdGFja2VkIGNvbHVtbiBjaGFydCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGRpc3RyaWJ1dGlvbiBvZiBtb3ZpZXMgdGhhdCBwYXNzIHRoZSBCZWNoZGVsIHRlc3QgYnkgZGlmZmVyZW50IG1vdmllIHNldHMuIFRoZSB4LWF4aXMgcmVwcmVzZW50cyB0aGUgbW92aWUgc2V0cywgYW5kIHRoZSB5LWF4aXMgcmVwcmVzZW50cyB0aGUgcGVyY2VudGFnZSBvZiBtb3ZpZXMgdGhhdCBwYXNzIHRoZSBCZWNoZGVsIHRlc3QuIFRoZSBjaGFydCBpcyBkaXZpZGVkIGludG8gZml2ZSBjYXRlZ29yaWVzIGJhc2VkIG9uIHRoZSBCZWNoZGVsIHRlc3Qgc2NvcmU6IG5vIHdvbWVuLCBubyB0YWxrLCBtZW4sIGR1YmlvdXMsIGFuZCBvay4gVGhlIHRvb2x0aXAgc2hvd3MgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIGZvciBlYWNoIGNhdGVnb3J5IGFuZCBtb3ZpZSBzZXQuIn0KI0ZpZ3VyZSA0CgoKZmlnNDwtaGNoYXJ0KGpvaW50YXYsICJjb2x1bW4iLCBoY2Flcyh4ID0gc2V0X2ZhY3RvciwgeSA9IGNvdW50LCBncm91cCA9IGNsZWFuX3Rlc3QpLCBzdGFja2luZyA9ICJwZXJjZW50IikgJT4lIAogIGhjX3RpdGxlKHRleHQgPSAiQmVjaGRlbCBUZXN0IFNjb3JlcyIpICU+JSAKICBoY19jb2xvcnMoY29sb3JzKSAlPiUgCiAgaGNfdG9vbHRpcChwb2ludEZvcm1hdCA9ICJ7c2VyaWVzLm5hbWV9OiB7cG9pbnQucGVyY2VudGFnZTouMWZ9JSIpICU+JSAKICBoY195QXhpcyh0aXRsZSA9ICJQZXJjZW50YWdlIiwgbGFiZWxzID0gbGlzdChmb3JtYXQgPSAne3ZhbHVlfSUnKSkgJT4lCiAgaGNfeEF4aXModGl0bGUgPSBOVUxMKSAlPiUgCiAgaGNfY29sb3JzKGNvbG9ycykgJT4lIAogIGhjX2xlZ2VuZChlbmFibGVkID0gVFJVRSkKYGBgCgojIE90aGVyIFNvdXJjZXMKCkJydWVnZ2VtYW5uLCBUb20uICJUaGVhdGVyIEF1ZGllbmNlcyBTaHJhbmsgYnkgSGFsZiBpbiB0aGUgTGFzdCA0IFllYXJzLgpDYW4gTW92aWVzIEdldCBUaGVtIEJhY2s/IiBJTURiLCA1IEphbnVhcnkgMjAyMywKPGh0dHBzOi8vd3d3LmltZGIuY29tL25ld3Mvbmk2Mzg5OTQwOD4uIEFjY2Vzc2VkIDMgTWF5IDIwMjMuIDxicj4KSGlja2V5LCBXYWx0LCBldCBhbC4gQ3JlYXRpbmcgVGhlIE5leHQgQmVjaGRlbCBUZXN0IFx8IEZpdmVUaGlydHlFaWdodCwKMjEgRGVjZW1iZXIgMjAxNywgPGh0dHBzOi8vcHJvamVjdHMuZml2ZXRoaXJ0eWVpZ2h0LmNvbS9uZXh0LWJlY2hkZWwvPi4KQWNjZXNzZWQgMyBNYXkgMjAyMy4gPGJyPiAiSU1EYi4iIFdpa2lwZWRpYSwKPGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lNRGI+LiBBY2Nlc3NlZCAzIE1heSAyMDIzLiA8YnI+ClJleW5vbGRzLCBNYXR0LiAiWW91IHNob3VsZCBpZ25vcmUgZmlsbSByYXRpbmdzIG9uIElNRGIgYW5kIFJvdHRlbgpUb21hdG9lcy4iIFdpcmVkIFVLLCAyNCBPY3RvYmVyIDIwMTcsCjxodHRwczovL3d3dy53aXJlZC5jby51ay9hcnRpY2xlL3doaWNoLWZpbG0tcmFua2luZy1zaXRlLXNob3VsZC1pLXRydXN0LXJvdHRlbi10b21hdG9lcy1pbWRiLW1ldGFjcml0aWM+LgpBY2Nlc3NlZCAzIE1heSAyMDIzLiA8YnI+IFVnd3UsIFJlZ2dpZS4gIlRoZSBIYXNodGFnIFRoYXQgQ2hhbmdlZCB0aGUKT3NjYXJzOiBBbiBPcmFsIEhpc3RvcnkgKFB1Ymxpc2hlZCAyMDIwKS4iIFRoZSBOZXcgWW9yayBUaW1lcywgOQpTZXB0ZW1iZXIgMjAyMCwKPGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjAvMDIvMDYvbW92aWVzL29zY2Fyc3Nvd2hpdGUtaGlzdG9yeS5odG1sPi4KQWNjZXNzZWQgMyBNYXkgMjAyMy4gPGJyPiBXYXRraW5zLCBBbGJlcnQuICJSYWNlIGFuZCBldGhuaWNpdHkgaW4gdGhlClVuaXRlZCBTdGF0ZXMuIiBXaWtpcGVkaWEsCjxodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SYWNlX2FuZF9ldGhuaWNpdHlfaW5fdGhlX1VuaXRlZF9TdGF0ZXM+LgpBY2Nlc3NlZCAzIE1heSAyMDIzLgo=